I'm using springdoc-openapi-ui for API documentation
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
And, following Spring Boot security config.
.
.
public static String[] SWAGGER_WHITELIST = {
"/api-docs",
"/swagger-ui.html",
"/swagger-resources/**",
"/webjars/**",
"/swagger.json"
};
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors().disable();
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http
.authorizeHttpRequests()
.requestMatchers(SWAGGER_WHITELIST).permitAll()
.requestMatchers(AUTH_WHITELIST).permitAll()
.and()
.addFilterAt(new JWTAuthenticationFilter(userService, jwtService, authenticationProvider()), UsernamePasswordAuthenticationFilter.class)
// .addFilterAfter(new UserAuthorizationFilter(), JWTAuthenticationFilter.class)
.authorizeHttpRequests()
.anyRequest().authenticated();
return http.build();
}
.
.
Spring boot parent version: 3
When I try to access http://localhost:8080/swagger-ui.html I'm getting 403.
Anyone facing similar issue? What could be the issue?
I tried
Whitelisting the swagger URLs
Changing the swagger doc path from config
I'm getting
No luck in debugging as console doesn't show any exception
It just rejects requests without printing any log
Following changes fixed the issue for me
Changed from springdoc-openapi-ui:1.6.14 to springdoc-openapi-starter-webmvc-ui:2.0.2 as it supports spring boot v3.
Added following things to whitelist
public static String[] SWAGGER_WHITELIST = {
"/api-docs/**",
"/api-docs.yaml",
"/swagger-ui/**",
"/swagger-ui.html",
};
New .properties file (match with whitelist)
#Swagger
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.api-docs.path=/api-docs
Related
i am trying to add couple of filters in my request processing in spring boot security config.
Below is my code
#EnableWebSecurity
#Configuration
public class JwtSecurityConfiguration {
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(this::configureEndpoints)
return http.build();
}
private void configureEndpoints(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorizationManagerRequestMatcherRegistry){
authorizationManagerRequestMatcherRegistry.mvcMatchers("/permit")
.permitAll()
.mvcMatchers("/block")
.denyAll()
.and()
.mvcMatcher("/api")
.addFilterBefore(new Filter1(), SecurityContextHolderAwareRequestFilter.class)
// register TenantFilter in the chain after the SecurityContext is made available by the respective filter
.mvcMatcher("/api")
.addFilterAfter(new Filter2(), SecurityContextHolderAwareRequestFilter.class)
.authorizeHttpRequests()
.mvcMatchers("/api")
.authenticated()
.and();
}
}
It seems the authentication does not happen and filters are never hit.
If i try to access the authentication in my runtime code i get SecurityContextHolder.getContext().getAuthentication() as null.
Seems to some problem in the security configuration only.
I'm trying to setup my Spring Boot 3.0 / Spring Security 6 app with multiple security configs.
only /oauth/token should use/allow/enforce basic auth
all other endpoints will use/allow/enforce bearer auth
The issue I'm running into is that if I send a GET request to /test with the header Authorization: Basic xxx the basic auth filter is still picking it up.
This is what I have so far. The bearer filter isn't implemented yet, but for the sake of this question, let's assume all other endpoints should be wide open instead. How can I get them to bypass the basic auth filter if a user passes in basic auth header?
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests()
.requestMatchers("/oauth/token").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic(Customizer.withDefaults());
return http.build();
}
Like this one:
private static final String[] RESOURCE_ARGS = new String[]{
"/test/**"
};
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests()
.requestMatchers(RESOURCE_ARGS).permitAll();
http
.csrf(CsrfConfigurer::disable)
.authorizeHttpRequests()
.requestMatchers("/oauth/token").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic(Customizer.withDefaults());
....
}
The following SecurityWebFilterChain works very fine in Spring Boot 2.7.x but not working any more in Spring Boot 3.0.0. It just show "An expected CSRF token cannot be found" when calling the REST API in Postman. Would you please to teach me how to solve it?
#Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
http
.cors().disable()
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint((swe, e) ->
Mono.fromRunnable(() -> swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED))
).accessDeniedHandler((swe, e) ->
Mono.fromRunnable(() -> swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN))
)
.and()
.authenticationManager(authenticationManager)
.securityContextRepository(securityContextRepository)
.authorizeExchange(exchange -> exchange
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.pathMatchers("/login", "/register").permitAll()
.anyExchange().authenticated()
.and()
.cors().disable()
.csrf().disable()
)
.formLogin().disable()
.httpBasic().disable()
;
return http.csrf(csrf -> csrf.disable()).build();
}
I experienced the same symptoms when migrating my webflux application to Spring Boot 3.0.0 today, which worked perfectly with 2.7.5. So I googled for "csrf-disabling no longer working" and found this and some few other posts...
However in my case, it was an annotation change of Spring security 6, that caused the problem: #EnableWebFluxSecurity contained "#Configuration" in 5.x version (I checked) - but obviously does no longer and has to be added explicitly.
Thus the complete SecurityWebFilterChain bean was not found after migrating... Now the working code looks as follows:
#EnableWebFluxSecurity
#Configuration // <- this was integrated in #EnableWebFluxSecurity with Spring Security 5.x
public class AccountWebSecurityConfig {
#Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,
ReactiveAuthenticationManager authenticationManager,
ServerAccessDeniedHandler accessDeniedHandler,
ServerAuthenticationEntryPoint authenticationEntryPoint) {
http.csrf().disable()
.httpBasic(httpBasicSpec -> httpBasicSpec
.authenticationManager(authenticationManager)
// when moving next line to exceptionHandlingSpecs, get empty body 401 for authentication failures (e.g. Invalid Credentials)
.authenticationEntryPoint(authenticationEntryPoint)
)
.authorizeExchange()
//...
}
As your FilterChain - snippet does not show the annotations at your class, chances are, you may also missing the #Configuration
In my case now everything works as before :-)
You can try it out
https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html
application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://idp.example.com/issuer
You forgot to enable resource-server in your filter-chain:
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(authenticationConverter)
You need a custom authentication converter, as done above, mostly for roles mapping.
Detailed tutorials (for servlets) here: https://github.com/ch4mpy/spring-addons/tree/master/samples/tutorials. You might then refer to samples for reactive apps.
Our spring boot 2.5.12 app is secured w/ a security configuration like this:
protected void configure(HttpSecurity http) throws Exception {
http
.cors().configurationSource(corsConfigurationSource)
.and()
.csrf()
.ignoringAntMatchers("/")
.and()
.authorizeRequests(authorizeRequests -> authorizeRequests
.mvcMatchers(GET, "/endpoint").hasAuthority("SCOPE_" + (Scope.READ))
.mvcMatchers(GET, "/endpoint/{reference}").permitAll()
.mvcMatchers(GET, "/error").permitAll()
.mvcMatchers(GET, "/info").permitAll()
.mvcMatchers(GET, "/health").permitAll()
.anyRequest().denyAll())
.oauth2ResourceServer()
.authenticationManagerResolver(authenticationManager())
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint);
}
w/ an AuthenticationManagerResolverBean:
public AuthenticationManagerResolver<HttpServletRequest> authenticationManager() {
return request -> {
...
...
...
};
}
it looks as if there's a bug as when i access the endpoint: /endpoint/ref123 it calls the AuthenticationManagerResolver even though this endpoint is open with a .permitAll(). So in the case the user accidentally provides an invalid token on this .permitAll() endpoint they aren't rejected.
if an endpoint is a .permitAll() then shouldn't spring not try to validate the token?
I didn't quite find why this is the behavior but we did find a workaround of sorts.
public void configure(WebSecurity web) {
web
.ignoring()
.mvcMatchers(GET, "/endpoint/{reference}");
}
It gets spring security to ignore tokens all together... valid or otherwise (which is what i thought permitAll did).
I'm trying to implement JWT in Spring Boot. For some debugging purposes, I need an H2 console.
So in my WebSecurityConfiguration, I wrote :
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
//httpSecurity.headers().frameOptions().disable();
httpSecurity.authorizeRequests().antMatchers("/h2").permitAll();
httpSecurity
.csrf().disable()
.authorizeRequests()
.antMatchers("/auth/check/username").permitAll()
.antMatchers("/auth/signup").permitAll()
.antMatchers("/auth/login").permitAll()
.anyRequest().authenticated().and()
.exceptionHandling().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
In my application properties, I have this configuration :
spring.h2.console.enabled=true
spring.h2.console.path=/h2
When I hit ":8080/h2", it gives me 403.
So the question remains, how can I properly configure Spring Boot Web Security.
After including /h2/**, I get this UI :
Please try "h2" pattern as:
httpSecurity.authorizeRequests().antMatchers("/h2/**").permitAll();
And this too :
httpSecurity.headers().frameOptions().disable();
more can found here : How to disable 'X-Frame-Options' response header in Spring Security?