In my SpringBoot app I keep getting error 403 on /swagger-ui - spring-boot

I know this may be a duplicated question but I've already tried all the solutions on the existing ones. In my project I have imported these dependencies:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
I configure swagger with this class:
#Configuration
#EnableSwagger2
#EnableWebMvc
public class SwaggerConfiguration implements WebMvcConfigurer{
#Bean
public Docket api() {
var logger = LoggerFactory.getLogger(SwaggerConfiguration.class);
logger.info("configuring swagger");
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
I have both .antMatchers("/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**" ,"/swagger.json").permitAll()
and web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**");
because the internet couldn't make up it's mind on which should be used, but nothing works, if I go at /v2/api-docs I get some json wall-text with all my endpoints tho

Related

how to configure Spring security without WebSecurityConfigurerAdapter class in spring boot 3

Now without the WebSecurityConfigurerAdapter I am trying to update this security configuration like this:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig{
#Autowired
private UserDetailsServiceImpl userDetailsService;
#Autowired
private AuthEntryPointJwt authenticationEntryPoint;
#Bean
public AuthTokenFilter authTokenFilter(){
return new AuthTokenFilter();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
#Bean
protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests().requestMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and();
http.addFilterBefore(authTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
}
But I get the following error:
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-02-06T13:29:11.394+01:00 ERROR 1524 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method setFilterChains in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a bean named 'A Bean named mvcHandlerMappingIntrospector of type org.springframework.web.servlet.handler.HandlerMappingIntrospector is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.' that could not be found.
Action:
Consider defining a bean named 'A Bean named mvcHandlerMappingIntrospector of type org.springframework.web.servlet.handler.HandlerMappingIntrospector is required to use MvcRequestMatcher. Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext.' in your configuration.
I would appreciate any kind of help that would be most welcome.
I used the following relevant dependencies and it starts with spring-boot-starter-parent 3.0.1:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>

How can I bypass authentication for Swagger-UI?

How can I bypass token authentication for Swagger-UI from browser?
I can make requests to Swagger-UI via Postman.
When I make a request from the browser, I get an error because it requests a token.
http://localhost:8080/swagger-ui/index.html
How can I fix?
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
Main class
#SpringBootApplication
public class ExampleMain {
public static void main(String[] args) {
SpringApplication.run(ExampleMain.class, args);
}
}
Security class
#Configuration
#EnableWebSecurity
public class SecurityConfig {
private JwtConverter wtConverter;
public SecurityConfig(JwtConverter jwtConverter) {
this.jwtConverter = jwtConverter;
}
#Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/swagger-ui/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(jwtConverter);
return http.build();
}
}
Apart from /swagger-ui/**, you should also permit access to OpenAPI documentation and Swagger resources:
...antMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**", "/swagger-resources").permitAll()

swagger return `Whitelabel Error Page` for url `../swagger-ui.html`

I followed this link: a Chinese introduction article, according to it, I only need to add the dependencies in pom.xml. (./v2/api-docs has been always working.)
It used to work, but today it breaks.
my swagger dependencies in pom.xml file
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
I am using spring boot 2.3.3, and swagger 2.9.2 .
in SwaggerConfig.java,
add below codes:
#Configuration
#EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
...
#Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
With newer versions of spring boot, this can be achieved with a property:
spring.resources.static-locations=classpath:/static/,classpath:/static/vendor/,classpath:/static/custom/
Also, make sure you configure SpringSecurity class to accept requests to this resources
#Override
public void configure(WebSecurity web)
{
web.ignoring()
.antMatchers( "/static/**","/resources/**", "/js/**", "/css/**", "/images/**");
}

How to add /api before swagger-ui.html

How to add default parameter before swagger-ui.html
Like this:
http://localhost:8080/api/swagger-ui.html
What I have integrated so far:
Pom.xml:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
SwaggerConfig.java:
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
Do I have to map "swagger-ui.html" to something with #RequestMapping?
Try this:
new Docket(DocumentationType.SWAGGER_2)
.host("www.mydomain.com")
.pathProvider(new RelativePathProvider(servletContext) {
#Override
public String getApplicationBasePath() {
return "/myapi";
}
});
in case you run into any issues: https://github.com/springfox/springfox/issues/1443
Include the following annotations at class level in SwaggerConfig.java:
#PropertySource("classpath:swagger.properties") and
#ComponentScan
Then create the swagger.properties file in the resources directory (same location as your application.properties file)

Spring boot h2-console not working

Hello I am not able to open h2-console with spring boot
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RC1</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
SpringSecurity Cfg:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("admin").roles("ADMIN").and()
.withUser("user").password("user").roles("USER");
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll()
.and()
.exceptionHandling().accessDeniedPage("/Access_Denied")
.and()
.csrf();
}
}
#SpringBootApplication
public class SpringBootWebSecureApplication {
#Bean
public Java8TimeDialect java8TimeDialect() {
return new Java8TimeDialect();
}
public static void main(String[] args) {
SpringApplication.run(SpringBootWebSecureApplication.class);
}
}
I am starting boot with:
-Dserver.port=8090
-Dspring.h2.console.enabled=true
-Dspring.datasource.url=jdbc:h2:mem:testdb
-Dspring.datasource.username=sa
-Dspring.datasource.driverClassName=org.h2.Driver
Logs:
2015-11-13 17:37:47 [restartedMain] DEBUG c.m.a.SpringBootWebSecureApplication - Running with Spring Boot v1.3.0.RC1, Spring v4.2.2.RELEASE
2015-11-13 17:37:49 [restartedMain] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat initialized with port(s): 8090 (http)
2015-11-13 17:37:50 [localhost-startStop-1] INFO o.s.b.c.e.ServletRegistrationBean - Mapping servlet: 'webServlet' to [/h2-console/*]
2015-11-13 17:37:51 [localhost-startStop-1] INFO o.s.s.web.DefaultSecurityFilterChain - Creating filter chain: Ant [pattern='/h2-console/**'], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#11ffd6f0, org.springframework.security.web.context.SecurityContextPersistenceFilter#615c57c5, org.springframework.security.web.header.HeaderWriterFilter#6b2cbcbf, org.springframework.security.web.authentication.logout.LogoutFilter#af7bece, org.springframework.security.web.authentication.www.BasicAuthenticationFilter#17d03ab2, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#613197b, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#8d48442, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#7fa13240, org.springframework.security.web.session.SessionManagementFilter#9f16a1c, org.springframework.security.web.access.ExceptionTranslationFilter#1f3f02ef, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#115de1f6]
But when I open browser with my app
console not appearing
http://localhost:8090/h2-console/
Any hints?
Thank you
Same here, I think it's the Java8TimeDialect Bean, in your case. In my case, I have a DandelionDialect Bean and when I remove it the h2-console works again.... Try removing the Java8TimeDialect to see if the console works.
Something related with the spring boot DispatcherServletAutoConfiguration?, the order in which the servlets are created or mapped? Not really sure...
http.headers().frameOptions().disable();
You can try following configuration class:
import org.h2.server.web.WebServlet;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import javax.servlet.DispatcherType;
import java.util.EnumSet;
#Configuration
public class WebConfiguration {
private static final String mapping = "/console/*";
#Bean
public ServletRegistrationBean h2servletRegistration(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean( new WebServlet());
registrationBean.addUrlMappings(mapping);
return registrationBean;
}
#Bean
public FilterRegistrationBean shallowEtagHeaderFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ShallowEtagHeaderFilter());
registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
registration.addUrlPatterns(mapping);
return registration;
}
}

Resources