I use spring security, I try to allow a post without need to be connected.
So in a class who extends WebSecurityConfigurerAdapter
#Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers(
"/",
"/help**",
"/css/**",
"/js/**",
"/img/**").permitAll()
.antMatchers(HttpMethod.POST, "/printdownload**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.successHandler(customAuthenticationSuccessHandler)
.and()
.logout();
}
When I try to call this controller
#PostMapping("/printdownload")
public String printTestament(#RequestBody TestamentWizard testamentDocuement){
....
}
I get this
o.s.security.web.FilterChainProxy : Securing POST /printdownload
s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/printdownload
o.s.s.w.access.AccessDeniedHandlerImpl : Responding with 403 status code
w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
o.s.security.web.FilterChainProxy : Securing POST /error
s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [POST /error] with attributes [authenticated]
o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:8080/login
w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
o.s.security.web.FilterChainProxy : Securing GET /login
s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
o.s.s.w.a.i.FilterSecurityInterceptor : Authorized filter invocation [GET /login] with attributes [permitAll]
o.s.security.web.FilterChainProxy : Secured GET /login
w.c.HttpSessionSecurityContextRepository : Did not store anonymous SecurityContext
w.c.HttpSessionSecurityContextRepository : Did not store anonymous SecurityContext
s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
Just don't understand why post is secured when i specified to permit it
Spring Security secures requests through defense in depth. Because of this, access rules like permitAll() and authenticated() are not the only thing protecting the web application.
In your case, CSRF protection is rejecting the request because it is enabled by default along with other protection against exploits. You can read about CSRF protection and why POST requests require a CSRF token in the reference docs.
Related
I have simple spring-boot rest api service with following security config:
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().disable();
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/Events/**").permitAll()
.antMatchers(String.format("%s/**", restApiDocPath)).permitAll()
.antMatchers(String.format("%s/**", swaggerPath)).permitAll()
.antMatchers("/api/users/**").hasAuthority(SmUserRole.ROLE_ADMIN_STR)
.anyRequest().authenticated()
.and()
.httpBasic();
return http.build();
}
Unauthorized access to /api/users/ return 401 as expected but in logs I have request to /error url and AccessDeniedException in result:
o.s.security.web.FilterChainProxy : Securing GET /api/users/?page=0&size=20
s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /api/users/?page=0&size=20] with attributes [hasAuthority('ROLE_ADMIN')]
s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#394122fd
s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
o.s.security.web.FilterChainProxy : Securing GET /error?page=0&size=20
s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
o.s.security.web.FilterChainProxy : Secured GET /error?page=0&size=20
a.DefaultWebInvocationPrivilegeEvaluator : filter invocation [/error] denied for AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]
org.springframework.security.access.AccessDeniedException: Access is denied
I dont have /error endpoint in this service. What's the cause of this behavior?
BasicAuthenticationEntryPoint adds "WWW-Authenticate" header and sends UNAUTHORIZED error response, there is nothing about /error.
I'm trying to make an authenticated GET request on one of the resources:
http://user:psw#localhost:8090/devices
This works fine from the browser. But from National Instrument GWeb I keep getting Code 401 (Unauthorized).
SecurityConfiguration.java:
#Configuration
#EnableWebSecurity
class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final DatabaseUserDetailsService databaseUserDetailsService;
public SecurityConfiguration(DatabaseUserDetailsService databaseUserDetailsService) {
super();
this.databaseUserDetailsService = databaseUserDetailsService;
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
#Bean
public AuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(this.databaseUserDetailsService);
return provider;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://rog-valerio", "http://localhost:8090"));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "OPTIONS"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
From the configure() method:
httpSecurity.cors().and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
I'm I am not wrong this should mean that any request should be able to authenticate.
By enabling spring security debug, when I try to make the authenticated request I get the following:
2022-03-09 10:37:00.520 DEBUG 27408 --- [nio-8090-exec-5] o.s.security.web.FilterChainProxy : Securing GET /devices
2022-03-09 10:37:00.520 DEBUG 27408 --- [nio-8090-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-03-09 10:37:00.521 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2022-03-09 10:37:00.521 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [GET /devices] with attributes [authenticated]
2022-03-09 10:37:00.522 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8090/devices to session
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#30dfc62d
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2022-03-09 10:37:00.523 DEBUG 27408 --- [nio-8090-exec-5] o.s.security.web.FilterChainProxy : Securing GET /error
2022-03-09 10:37:00.524 DEBUG 27408 --- [nio-8090-exec-5] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-03-09 10:37:00.524 DEBUG 27408 --- [nio-8090-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2022-03-09 10:37:00.524 DEBUG 27408 --- [nio-8090-exec-5] o.s.security.web.FilterChainProxy : Secured GET /error
2022-03-09 10:37:00.525 DEBUG 27408 --- [nio-8090-exec-5] a.DefaultWebInvocationPrivilegeEvaluator : filter invocation [/error] denied for AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=05282221D24CA222616679CE3049C092], Granted Authorities=[ROLE_ANONYMOUS]]
org.springframework.security.access.AccessDeniedException: Access is denied
And access is denied. Username and password are correct. Why am I getting the request rejected? Maybe there is some configuration that I am missing?
I found the answer, configuration was fine. But, as stated here https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization#examples , I added "Authorization" header with base64 encoded username and password. Now it works.
I'll not delete the question because maybe it'll be useful to somebody
I'm trying to implement a JWT based authentication using spring security in a spring boot API, but I don't know what I'm doing wrong. On my implementation of WebSecurityConfigurerAdapter I permit access to auth/** resource, but when I make a request to, for example, /auth/login, I get a 403. It seems that it is ignoring the "public" resources.
The csrf() is disabled.
This is the repository: https://github.com/wallysoncarvalho/jwt-auth-spring-security
I enabled DEBUG mode and that's what I get:
Request received for POST '/auth/login?username=wally&password=wally':
org.apache.catalina.connector.RequestFacade#585d8cc6
servletPath:/auth/login
pathInfo:null
headers:
user-agent: PostmanRuntime/7.26.8
accept: */*
postman-token: 91c2a071-a353-4d77-9c7c-b04a43b94081
host: localhost:8091
accept-encoding: gzip, deflate, br
connection: keep-alive
content-length: 0
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
JwtFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2020-12-22 20:21:15.919 DEBUG 6288 --- [nio-8091-exec-2] o.s.security.web.FilterChainProxy : Securing POST /auth/login?username=wally&password=wally
2020-12-22 20:21:15.937 DEBUG 6288 --- [nio-8091-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2020-12-22 20:21:15.948 DEBUG 6288 --- [nio-8091-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
2020-12-22 20:21:15.960 INFO 6288 --- [nio-8091-exec-2] Spring Security Debugger :
************************************************************
Request received for POST '/error?username=wally&password=wally':
org.apache.catalina.core.ApplicationHttpRequest#6d88bc8c
servletPath:/error
pathInfo:null
headers:
user-agent: PostmanRuntime/7.26.8
accept: */*
postman-token: 91c2a071-a353-4d77-9c7c-b04a43b94081
host: localhost:8091
accept-encoding: gzip, deflate, br
connection: keep-alive
content-length: 0
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
JwtFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2020-12-22 20:21:15.961 DEBUG 6288 --- [nio-8091-exec-2] o.s.security.web.FilterChainProxy : Securing POST /error?username=wally&password=wally
2020-12-22 20:21:15.961 DEBUG 6288 --- [nio-8091-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2020-12-22 20:21:15.967 DEBUG 6288 --- [nio-8091-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2020-12-22 20:21:15.998 DEBUG 6288 --- [nio-8091-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Failed to authorize filter invocation [POST /error?username=wally&password=wally] with attributes [authenticated]
2020-12-22 20:21:16.022 DEBUG 6288 --- [nio-8091-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2020-12-22 20:21:16.025 DEBUG 6288 --- [nio-8091-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/assets/**",);
}
And your #Configuration class must implements WebMvcConfigurer
Edit
Also enable WebSecurity in your config class by annotating it with #EnableWebSecurity
We have a CustomAuthenticationProvider(AuthenticationProvider) developed for Spring which works with CustomAuthenticationRequest(Authentication), CustomAuthentication(Authentication), a CustomUser.
Once we validate credentials when our Controller is invoked we create a CustomAuthenticationRequest based on the credentials.
SecurityContext securityContext = SecurityContextHolder.getContext();
securityContext.setAuthentication(new CustomAuthenticationRequest(new CustomUser(account.getUsername())));
Debug login confirms that the CustomAuthenticationRequest has been stored in the HTTPSession.
HttpSessionSecurityContextRepository - SecurityContext 'org.springframework.security.core.context.SecurityContextImpl#730db7d8: Authentication: pro.someplace.spring.CustomAuthenticationRequest#730db7d8' stored to HttpSession: 'org.apache.catalina.session.StandardSessionFacade#5da80010
The WebSecurityConfigurerAdapter registers our AuthenticationProvider:
#Override
public void configure(AuthenticationManagerBuilder builder)
throws Exception {
builder.authenticationProvider(new CustomAuthenticationProvider());
}
And establishes what can and cannot be seen by anonymous and authenticated users.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/registration").permitAll()
.anyRequest()
.authenticated();
}
The problem we have is that before the FilterSecurityInterceptor can consult which AuthenticationProvider is appropriate the AnonymousAuthenticationFilter steps in:
o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#4cc1f847: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: 74DB809F1CB5CFB1F977EC20B37B218E; Granted Authorities: ROLE_ANONYMOUS'
If I remove the AnonymousAuthenticationFilter then I cannot access permitAll() in the configuration (different error).
Curiously, I notice this logging message at the end of request processing:
SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
Ok. So the SecurityContextPersistenceFilter should have persisted the context in the HttpSessionSecurityContextRepository.
But when the next request appears the SecurityContextPersistenceFilter has no such object. Was it saved at all? Was it removed?
o.s.security.web.FilterChainProxy - /ordervalidator at position 2 of 10 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
o.s.s.w.c.HttpSessionSecurityContextRepository - No HttpSession currently exists
o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
How can I configure spring to allow authenticated users where I want them and use my CustomAuthenticationProvider when available in the HTTPSession? Where is the security object and why is it not being stored?
And so will be as dumb as it sounds. The front end is React and so we were returning a cookie to the front end however the front end was not being returned to us. As soon as I manually insert cookies into requests I have trapped in either (Postman or Burp) my Context can be found.
This is a cautionary tale as there is a generational difference between the frontend React and the backend (Spring) developers. The backend expect cookies and this is assumed, the front end "...have no idea why we would want them and its a bad idea".
How can I set up a custom login form to protect my /oauth/authorize endpoint in an Spring Boot Application that is both a Authorization and Resource Server? I want to achieve that a user has to log in to make requests to /oauth/authorize. All resources, that are not /login and /oauth/** should be handled as secured resources protected by OAuth (requiring a valid access token)
So when a user calls localhost:1234/oauth/authorize?client_id=client&response_type=token&redirect_uri=http://localhost:5678 he is first redirected to the login form and after successfully loggin in redirect to the /oauth/authorize endpoint where the implicit OAuth flow proceeds.
When I try the following it works, using the standard basic authentication popup window
#Configuration
#EnableAuthorizationServer
public class OAuthConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(final ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("implicit", "refresh_token")
.scopes("read");
}
}
The Resource config
#Configuration
#EnableResourceServer
public class ResourceConfiguration
extends ResourceServerConfigurerAdapter
{
#Override
public void configure(final HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests().antMatchers("/login").permitAll().and()
.authorizeRequests().anyRequest().authenticated();
// #formatter:on
}
}
The Web Security config
#Configuration
public class WebSecurityConfiguration
extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/oauth/authorize").authenticated().and()
.authorizeRequests().anyRequest().permitAll().and().httpBasic();
}
}
but as soon as I replace httpBasic() with the following it fails:
#Configuration
public class WebSecurityConfiguration
extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/oauth/authorize").authenticated().and()
.authorizeRequests().anyRequest().permitAll().and().formLogin().loginPage("/login").and().csrf()
.disable();
}
}
and my POST from the login Page is not redirected, it always just returns to /login
The output from the console is as following
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/css/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/js/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/images/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/**/favicon.ico'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/error'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/token']
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/oauth/token'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/token_key']
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/oauth/token_key'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/check_token']
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/oauth/check_token'
o.s.s.web.util.matcher.OrRequestMatcher : No matches found
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration$NotOAuthRequestMatcher#5fe3eb5f
o.s.s.web.util.matcher.OrRequestMatcher : matched
o.s.security.web.FilterChainProxy : /login at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
o.s.security.web.FilterChainProxy : /login at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
o.s.security.web.FilterChainProxy : /login at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#51c78264
o.s.security.web.FilterChainProxy : /login at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/logout'
o.s.security.web.FilterChainProxy : /login at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
o.s.s.o.p.a.BearerTokenExtractor : Token not found in headers. Trying request parameters.
o.s.s.o.p.a.BearerTokenExtractor : Token not found in request parameters. Not an OAuth2 request.
p.a.OAuth2AuthenticationProcessingFilter : No token in request, will continue chain.
o.s.security.web.FilterChainProxy : /login at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
o.s.security.web.FilterChainProxy : /login at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
o.s.security.web.FilterChainProxy : /login at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: BDCE2D7EA7252AEA2506633726B8BA19; Granted Authorities: ROLE_ANONYMOUS'
o.s.security.web.FilterChainProxy : /login at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
o.s.security.web.FilterChainProxy : /login at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
o.s.security.web.FilterChainProxy : /login at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/login'
o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /login; Attributes: [#oauth2.throwOnError(permitAll)]
o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: BDCE2D7EA7252AEA2506633726B8BA19; Granted Authorities: ROLE_ANONYMOUS
o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#bba9bfc, returned: 1
o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
o.s.security.web.FilterChainProxy : /login reached end of additional filter chain; proceeding with original chain
o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Adding an #Order(-10) to the WebSecurityConfig resolves the issue. I think this annoation ensures that the WebSecurityConfig is used before the ResourceConfig. My final configuration looks like this:
#Configuration
#Order(-10)
public class WebSecurityConfig
extends WebSecurityConfigurerAdapter
{
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests().antMatchers("/oauth/authorize").authenticated()
.and()
.authorizeRequests().anyRequest().permitAll()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.csrf().disable();
// #formatter:on
}
}