I added Spring Security (5.0.0.RELEASE) with JWT Authentication to Spring Boot (1.5.7.RELEASE), but the CORS seems to not work.
I added the CORS configuration as described here.
I also tried adding #CrossOrigin to the controllers, but it doesn't seem to change anything.
When calling POST and GET requests from the front-end (Angular JS 5) there doesn't seem to be any CORS problem, but when calling DELETE I get CORS error.
Here's the security configuration:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.antMatchers(HttpMethod.GET, ACTIVATE_URL).permitAll()
.antMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
// this disables session creation on Spring Security
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.addAllowedMethod(HttpMethod.TRACE);
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
And here are the headers from postman when sending OPTIONS request:
Allow →DELETE,GET,HEAD,POST
Cache-Control →no-cache, no-store, max-age=0, must-revalidate
Content-Length →0
Date →Fri, 12 Jan 2018 13:22:08 GMT
Expires →0
Pragma →no-cache
X-Content-Type-Options →nosniff
X-Frame-Options →DENY
X-XSS-Protection →1; mode=block
The allow-access-control-origin header is missing, as well as the HTTP TRACE I added to see if the configuration is working.
And the spring security debug logs:
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] 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#7ce27d90
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 4 of 13 in additional filter chain; firing Filter: 'CorsFilter'
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /api/stories/7' doesn't match 'GET /logout
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /api/stories/7' doesn't match 'POST /logout
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2018-01-12 14:22:08.621 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /api/stories/7' doesn't match 'PUT /logout
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /api/stories/7' doesn't match 'DELETE /logout
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 6 of 13 in additional filter chain; firing Filter: 'JWTAuthenticationFilter'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/stories/7'; against '/api/users/login'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 7 of 13 in additional filter chain; firing Filter: 'JWTAuthorizationFilter'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /api/stories/7' doesn't match 'POST /api/users/register
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'OPTIONS /api/stories/7' doesn't match 'GET /api/users/activate/**
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/stories/7'; against '/api/users/login'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/stories/7'; against '/api/users/request-reset-password'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/stories/7'; against '/api/users/reset-password'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/stories/7'; against '/api/stories'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/stories/7'; against '/api/stories/*'
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/stories/7; Attributes: [permitAll]
2018-01-12 14:22:08.622 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2018-01-12 14:22:08.623 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#703f0616, returned: 1
2018-01-12 14:22:08.623 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2018-01-12 14:22:08.623 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2018-01-12 14:22:08.623 DEBUG 15619 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : /api/stories/7 reached end of additional filter chain; proceeding with original chain
2018-01-12 14:22:08.630 DEBUG 15619 --- [nio-8080-exec-3] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2018-01-12 14:22:08.630 DEBUG 15619 --- [nio-8080-exec-3] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
And here are the logs for Invalid CORS request:
2018-01-12 15:47:09.445 DEBUG 17909 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /api/users/bank-accounts/ at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-01-12 15:47:09.445 DEBUG 17909 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /api/users/bank-accounts/ at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-01-12 15:47:09.445 DEBUG 17909 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /api/users/bank-accounts/ at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-01-12 15:47:09.445 DEBUG 17909 --- [nio-8080-exec-2] 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#7d9c9d3c
2018-01-12 15:47:09.446 DEBUG 17909 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /api/users/bank-accounts/ at position 4 of 13 in additional filter chain; firing Filter: 'CorsFilter'
2018-01-12 15:47:09.446 DEBUG 17909 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
When using a breakpoint as dur sugested it turned out allowMethods was always null
Adding the following line to corsConfigurationSource fixed it:
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "DELETE", "OPTIONS"));
Related
I have a Restful APIs developed using Springboot. Also, I have implementioned external ldap authentication.
http://localhost:8080/login?username=test&password=test goes through the ldap authentication and it is working fine as expected.
My Spring security implementation is below. I am restricting all the API calls and needs to be authenticated.
#Configuration
#EnableWebSecurity
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
...
...
}
My login request works and all the API calls are not getting authenticated, even after the successful login. I can see the logs show that ldap authentication is success and creates the SecurityContext. And my next API call does not have this SecurityContext created in the previous login request.
My logs are below.
2019-10-11 02:22:31.567 DEBUG 39216 --- [nio-8080-exec-1]
o.s.security.web.FilterChainProxy :
/login?username=test&password=test at position 5 of 11 in additional
filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2019-10-11 02:22:31.567 DEBUG 39216 --- [nio-8080-exec-1]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/login'; against '/login' 2019-10-11 02:22:31.567 DEBUG 39216 ---
[nio-8080-exec-1] w.a.UsernamePasswordAuthenticationFilter : Request
is to process authentication 2019-10-11 02:22:31.570 DEBUG 39216 ---
[nio-8080-exec-1] o.s.s.authentication.ProviderManager :
Authentication attempt using
portal.services.security.CustomActiveDirectoryLdapAuthenticationProvider
2019-10-11 02:22:32.767 DEBUG 39216 --- [nio-8080-exec-1]
o.s.s.ldap.SpringSecurityLdapTemplate : Searching for entry under
DN '', base = 'dc=abc,dc=com', filter = '(&(objectClass=Person)
((sAMAccountName=12323)))' 2019-10-11 02:22:32.777 DEBUG 39216 ---
[nio-8080-exec-1] o.s.s.ldap.SpringSecurityLdapTemplate : Found DN:
CN=Test Name,OU=Users,DC=com 2019-10-11 02:22:32.779 INFO 39216 ---
[nio-8080-exec-1] o.s.s.ldap.SpringSecurityLdapTemplate : Ignoring
PartialResultException 2019-10-11 02:22:32.896 DEBUG 39216 ---
[nio-8080-exec-1] o.s.s.l.u.LdapUserDetailsMapper : Mapping
user details from context with DN: CN=test name,OU=Users,DC=com
2019-10-11 02:22:32.899 DEBUG 39216 --- [nio-8080-exec-1]
s.CompositeSessionAuthenticationStrategy : Delegating to
org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy#45a4b042
2019-10-11 02:22:32.899 DEBUG 39216 --- [nio-8080-exec-1]
w.a.UsernamePasswordAuthenticationFilter : Authentication success.
Updating SecurityContextHolder to contain:
org.springframework.security.authentication.UsernamePasswordAuthenticationToken#ff0ce9d1:
Principal:
org.springframework.security.ldap.userdetails.LdapUserDetailsImpl#7a480d2:
Dn: CN=Test name,OU=Users,DC=com; Username: test; Password:
[PROTECTED]; Enabled: true; AccountNonExpired: true;
CredentialsNonExpired: true; AccountNonLocked: true; Granted
Authorities: ADMIN; Credentials: [PROTECTED]; Authenticated: true;
Details: Users; Granted Authorities: ADMIN 2019-10-11 02:22:33.117
DEBUG 39216 --- [nio-8080-exec-1]
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#17741df1
2019-10-11 02:22:33.117 DEBUG 39216 --- [nio-8080-exec-1]
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now
cleared, as request processing completed 2019-10-11 02:22:33.650 DEBUG
39216 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy :
/admin/getCutOffDays at position 1 of 11 in additional filter chain;
firing Filter: 'WebAsyncManagerIntegrationFilter' 2019-10-11
02:22:33.650 DEBUG 39216 --- [nio-8080-exec-2]
o.s.security.web.FilterChainProxy : /admin/getCutOffDays at
position 2 of 11 in additional filter chain; firing Filter:
'SecurityContextPersistenceFilter' 2019-10-11 02:22:33.654 DEBUG 39216
--- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : /admin/getCutOffDays at position 3 of 11 in additional filter chain;
firing Filter: 'HeaderWriterFilter' 2019-10-11 02:22:33.654 DEBUG
39216 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy :
/admin/getCutOffDays at position 4 of 11 in additional filter chain;
firing Filter: 'LogoutFilter' 2019-10-11 02:22:33.654 DEBUG 39216 ---
[nio-8080-exec-2] o.s.s.web.util.matcher.OrRequestMatcher : Trying to
match using Ant [pattern='/logout', GET] 2019-10-11 02:22:33.655 DEBUG
39216 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher :
Request 'OPTIONS /admin/getCutOffDays' doesn't match 'GET /logout
2019-10-11 02:22:33.655 DEBUG 39216 --- [nio-8080-exec-2]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/logout', POST] 2019-10-11 02:22:33.655 DEBUG 39216 ---
[nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request
'OPTIONS /admin/getCutOffDays' doesn't match 'POST /logout 2019-10-11
02:22:33.655 DEBUG 39216 --- [nio-8080-exec-2]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/logout', PUT] 2019-10-11 02:22:33.655 DEBUG 39216 ---
[nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request
'OPTIONS /admin/getCutOffDays' doesn't match 'PUT /logout 2019-10-11
02:22:33.656 DEBUG 39216 --- [nio-8080-exec-2]
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant
[pattern='/logout', DELETE] 2019-10-11 02:22:33.656 DEBUG 39216 ---
[nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request
'OPTIONS /admin/getCutOffDays' doesn't match 'DELETE /logout
2019-10-11 02:22:33.656 DEBUG 39216 --- [nio-8080-exec-2]
o.s.s.web.util.matcher.OrRequestMatcher : No matches found 2019-10-11
02:22:33.657 DEBUG 39216 --- [nio-8080-exec-2]
o.s.security.web.FilterChainProxy : /admin/getCutOffDays at
position 5 of 11 in additional filter chain; firing Filter:
'UsernamePasswordAuthenticationFilter' 2019-10-11 02:22:33.657 DEBUG
39216 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher :
Request 'OPTIONS /admin/getCutOffDays' doesn't match 'POST /login
2019-10-11 02:22:33.657 DEBUG 39216 --- [nio-8080-exec-2]
o.s.security.web.FilterChainProxy : /admin/getCutOffDays at
position 6 of 11 in additional filter chain; firing Filter:
'RequestCacheAwareFilter' 2019-10-11 02:22:33.657 DEBUG 39216 ---
[nio-8080-exec-2] o.s.security.web.FilterChainProxy :
/admin/getCutOffDays at position 7 of 11 in additional filter chain;
firing Filter: 'SecurityContextHolderAwareRequestFilter' 2019-10-11
02:22:33.659 DEBUG 39216 --- [nio-8080-exec-2]
o.s.security.web.FilterChainProxy : /admin/getCutOffDays at
position 8 of 11 in additional filter chain; firing Filter:
'AnonymousAuthenticationFilter' 2019-10-11 02:22:33.660 DEBUG 39216
--- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token:
'org.springframework.security.authentication.AnonymousAuthenticationToken#25109219:
Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated:
true; Details:
org.springframework.security.web.authentication.WebAuthenticationDetails#b364:
RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted
Authorities: ROLE_ANONYMOUS' 2019-10-11 02:22:33.661 DEBUG 39216 ---
[nio-8080-exec-2] o.s.security.web.FilterChainProxy :
/admin/getCutOffDays at position 9 of 11 in additional filter chain;
firing Filter: 'SessionManagementFilter' 2019-10-11 02:22:33.662 DEBUG
39216 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy :
/admin/getCutOffDays at position 10 of 11 in additional filter chain;
firing Filter: 'ExceptionTranslationFilter' 2019-10-11 02:22:33.671
DEBUG 39216 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy
: /admin/getCutOffDays at position 11 of 11 in additional filter
chain; firing Filter: 'FilterSecurityInterceptor' 2019-10-11
02:22:33.673 DEBUG 39216 --- [nio-8080-exec-2]
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request :
'/admin/getCutOffDays'; against '/login' 2019-10-11 02:22:33.674 DEBUG
39216 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor :
Secure object: FilterInvocation: URL: /admin/getCutOffDays;
Attributes: [authenticated] 2019-10-11 02:22:33.674 DEBUG 39216 ---
[nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor :
Previously Authenticated:
org.springframework.security.authentication.AnonymousAuthenticationToken#25109219:
Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated:
true; Details:
org.springframework.security.web.authentication.WebAuthenticationDetails#b364:
RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted
Authorities: ROLE_ANONYMOUS 2019-10-11 02:22:33.688 DEBUG 39216 ---
[nio-8080-exec-2] o.s.s.access.vote.AffirmativeBased : Voter:
org.springframework.security.web.access.expression.WebExpressionVoter#74f28afc,
returned: -1 2019-10-11 02:22:33.696 DEBUG 39216 --- [nio-8080-exec-2]
o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is
anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is
denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
~[spring-security-core-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
~[spring-security-core-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124)
~[spring-security-web-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
~[spring-security-web-5.0.8.RELEASE.jar!/:5.0.8.RELEASE]
I am expecting my request to /admin/getCutOffDays should retrieve the data as it is authenticated in the previous login request.
Below is my Controller.
#RequestMapping("/admin")
#RestController
public class AdminController {
#PreAuthorize("hasAuthority('ADMIN')")
#GetMapping("/getCutOffDays")
public long getCutOffDays() {
return adminService.getSequenceId(CUT_OFF_DAYS);
}
}
Can anyone help me figure out what am I missing here.
To answer your question correctly, I would need to have some more input from your side. I'll try to answer it by making some assumptions.
I'm assuming you're authenticating your application and then making a REST call afterward. First (as already mentioned in the answers), you have a STATELESS session policy. It means the session won't be available for the subsequent Http requests.
You can handle it by:
Implementing a token-based (transparent/opaque) authentication.
Implementing a basic-authentication.
In both cases, every request to your REST APIs requires an Authorization Header (or a Cookie, depends on the approach).
I've got a Spring Boot Application, with a RequestMapping to / for its Index-Page, I've created an docker image for easy hosting.
If I start the docker container and browse to localhost:8084 (I've exposed Port 3002 and mapped it to 8084) I get "HTTP Error 403 - Not Authorized" instead of redirecting to localhost:8084/user/login.
If I browse to localhost:8084/user/login I'll get the login page. I also set up an Apache with ReverseProxy on the Docker Host but also no difference.
So my Question what is going wrong here? If I start the Application without Docker there is no Problem and I'm redirected fine.
My Dockerfile looks like this:
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
VOLUME /tmp
RUN mkdir /deployment
VOLUME /deployment/data
ADD compareTestData.zip /deployment/data/compareTestData/
COPY target/${JAR_FILE} /deployment/app.jar
RUN sh -c 'touch /deployment/app.jar'
EXPOSE 3002
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/deployment/app.jar"]
My IndexController like this (I removed all unnecessary code) :
#Controller
#RequestMapping("/")
public class IndexController {
private Logger log = LoggerFactory.getLogger(getClass());
#RequestMapping
#PreAuthorize("hasPermission('index', 'get')")
public String getIndex(Model model, Principal principal) {
try {
return "index";
} catch (IllegalArgumentException e) {
log.error(e.getMessage(), e);
return "error";
}
}
}
My WebSecurityConfig:
#Configuration
public class FormWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
#Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(11);
}
#Bean
#Qualifier("sessionListener")
public ServletListenerRegistrationBean<HttpSessionListener> sessionListener() {
return new ServletListenerRegistrationBean<>(new SessionListener());
}
#Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/fonts/**").permitAll()
.antMatchers("/user", "/user/login", "/user/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/user/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.logoutUrl("/user/logout")
.permitAll();
}
}
The logging output as commented by PaulNUK:
2018-08-15 12:26:41.563 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Zugriff verweigert
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
# Stacktrace removed because of character limitation#
2018-08-15 12:26:41.564 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']]
2018-08-15 12:26:41.564 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/**/favicon.ico'
2018-08-15 12:26:41.564 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2018-08-15 12:26:41.564 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager#5e7e4311, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]]
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : httpRequestMediaTypes=[text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8]
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing text/html
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith text/html = false
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xhtml+xml
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xhtml+xml = false
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing image/webp
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith image/webp = false
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing image/apng
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith image/apng = false
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/xml;q=0.9
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/xml;q=0.9 = false
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing */*;q=0.8
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Ignoring
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.m.MediaTypeRequestMatcher : Did not match any media types
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2018-08-15 12:26:41.565 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2018-08-15 12:26:41.566 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2018-08-15 12:26:41.566 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.util.matcher.AndRequestMatcher : All requestMatchers returned true
2018-08-15 12:26:41.566 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.s.HttpSessionRequestCache : DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8084/]
2018-08-15 12:26:41.566 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
2018-08-15 12:26:41.566 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2018-08-15 12:26:41.566 DEBUG 1 --- [nio-3002-exec-6] 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#510c25f5
2018-08-15 12:26:41.566 DEBUG 1 --- [nio-3002-exec-6] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#2bf78a1f
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 1 of 9 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 2 of 9 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#1412c8a7. A new one will be created.
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 3 of 9 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 4 of 9 in additional filter chain; firing Filter: 'LogoutFilter'
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2018-08-15 12:26:41.567 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/error'; against '/logout'
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /error' doesn't match 'POST /logout
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /error' doesn't match 'PUT /logout
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /error' doesn't match 'DELETE /logout
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 5 of 9 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.s.DefaultSavedRequest : pathInfo: both null (property equals)
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.s.DefaultSavedRequest : queryString: both null (property equals)
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.s.DefaultSavedRequest : requestURI: arg1=/; arg2=/error (property not equals)
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.s.HttpSessionRequestCache : saved request doesn't match
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 6 of 9 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 7 of 9 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#3e9b471e: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffdaa08: RemoteIpAddress: 172.17.0.1; SessionId: 9B6893C62D8CE2E2072D343FA21B122C; Granted Authorities: ROLE_ANONYMOUS'
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 8 of 9 in additional filter chain; firing Filter: 'SessionManagementFilter'
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error at position 9 of 9 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.security.web.FilterChainProxy : /error reached end of additional filter chain; proceeding with original chain
2018-08-15 12:26:41.568 DEBUG 1 --- [nio-3002-exec-6] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2018-08-15 12:26:41.569 DEBUG 1 --- [nio-3002-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2018-08-15 12:26:41.570 DEBUG 1 --- [nio-3002-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
2018-08-15 12:26:41.570 DEBUG 1 --- [nio-3002-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'basicErrorController'
2018-08-15 12:26:41.570 DEBUG 1 --- [nio-3002-exec-6] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
2018-08-15 12:26:41.570 DEBUG 1 --- [nio-3002-exec-6] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2018-08-15 12:26:41.570 DEBUG 1 --- [nio-3002-exec-6] o.s.c.e.PropertySourcesPropertyResolver : Could not find key 'spring.template.provider.cache' in any property source
2018-08-15 12:26:41.571 DEBUG 1 --- [nio-3002-exec-6] o.s.c.e.PropertySourcesPropertyResolver : Could not find key 'spring.template.provider.cache' in any property source
2018-08-15 12:26:41.572 DEBUG 1 --- [nio-3002-exec-6] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html])
2018-08-15 12:26:41.573 DEBUG 1 --- [nio-3002-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'error'
2018-08-15 12:26:41.573 DEBUG 1 --- [nio-3002-exec-6] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$SpelView#49b2a47d] based on requested media type 'text/html'
2018-08-15 12:26:41.573 DEBUG 1 --- [nio-3002-exec-6] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$SpelView#49b2a47d] in DispatcherServlet with name 'dispatcherServlet'
2018-08-15 12:26:41.573 DEBUG 1 --- [nio-3002-exec-6] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2018-08-15 12:26:41.573 DEBUG 1 --- [nio-3002-exec-6] o.s.orm.jpa.EntityManagerFactoryUtils : Closing JPA EntityManager
2018-08-15 12:26:41.574 DEBUG 1 --- [nio-3002-exec-6] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-08-15 12:26:41.574 DEBUG 1 --- [nio-3002-exec-6] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2018-08-15 12:26:41.574 DEBUG 1 --- [nio-3002-exec-6] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2018-08-15 12:26:41.574 DEBUG 1 --- [nio-3002-exec-6] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2018-08-15 12:26:41.600 DEBUG 1 --- [nio-3002-exec-7] o.s.b.w.s.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#2bf78a1f
2018-08-15 12:26:41.600 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 1 of 9 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-08-15 12:26:41.600 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 2 of 9 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#1412c8a7. A new one will be created.
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 3 of 9 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 4 of 9 in additional filter chain; firing Filter: 'LogoutFilter'
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/favicon.ico'; against '/logout'
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /favicon.ico' doesn't match 'POST /logout
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /favicon.ico' doesn't match 'PUT /logout
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /favicon.ico' doesn't match 'DELETE /logout
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 5 of 9 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.s.DefaultSavedRequest : pathInfo: both null (property equals)
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.s.DefaultSavedRequest : queryString: both null (property equals)
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.s.DefaultSavedRequest : requestURI: arg1=/; arg2=/favicon.ico (property not equals)
2018-08-15 12:26:41.601 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.s.HttpSessionRequestCache : saved request doesn't match
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 6 of 9 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 7 of 9 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#3e9b471e: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffdaa08: RemoteIpAddress: 172.17.0.1; SessionId: 9B6893C62D8CE2E2072D343FA21B122C; Granted Authorities: ROLE_ANONYMOUS'
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 8 of 9 in additional filter chain; firing Filter: 'SessionManagementFilter'
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico at position 9 of 9 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.security.web.FilterChainProxy : /favicon.ico reached end of additional filter chain; proceeding with original chain
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/favicon.ico]
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/favicon.ico] are [/**/favicon.ico]
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/favicon.ico] are {}
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/favicon.ico] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/], class path resource []], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#7cbd9d24]]] and 1 interceptor
2018-08-15 12:26:41.602 DEBUG 1 --- [nio-3002-exec-7] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/favicon.ico] is: -1
2018-08-15 12:26:41.604 DEBUG 1 --- [nio-3002-exec-7] 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#510c25f5
2018-08-15 12:26:41.604 DEBUG 1 --- [nio-3002-exec-7] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2018-08-15 12:26:41.607 DEBUG 1 --- [nio-3002-exec-7] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2018-08-15 12:26:41.607 DEBUG 1 --- [nio-3002-exec-7] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-08-15 12:26:41.609 DEBUG 1 --- [nio-3002-exec-7] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2018-08-15 12:26:41.609 DEBUG 1 --- [nio-3002-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2018-08-15 12:26:41.609 DEBUG 1 --- [nio-3002-exec-7] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#2bf78a1f
Apache Config on Host:
<VirtualHost *:80>
ServerName layouter.localhost
ErrorLog "/private/var/log/apache2/layouter-error_log"
CustomLog "/private/var/log/apache2/layouter-access_log" common
ProxyPass / http://localhost:8084/
ProxyPassReverse / http://localhost:8084/
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
ProxyPreserveHost On
</VirtualHost>
I ran into this issue a week ago and I was getting the same 403 error in a similar setup with spring boot, front end and back end environment and a reverse proxy. The reason being in my case was that my port 8080 was occupied by another application at the same time and spring was not complaining about it. Instead of sending requests to my server, it was doing it to that application without me knowing, and therefore all connections to my back end were refused.
What resolved my issue was killing that extra process listening on port 8080 and afterwards, my backend started processing all requests sent by the proxy.
So if you came across this similar issue, don't hesitate to verify what apps are listening on your port before changing any configuration on your app.
Hope this help you save time.
sudo lsof -i -P | grep -i "listen"
I have a Spring Boot app and for some reason each request from client to css files receives HTML of login page in response. No error, no redirect, status is 200 and HTML is in response body. What can be the reason of it?
Login page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Sign in</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link th:href="#{/css/login.css}" rel="stylesheet" media="screen"/>
</head>
<body>
<div class="input-group outlet">
<p>Sign in</p>
<form th:action="#{/login}" method="post">
<div><input name="username"/></div>
<div><input name="password" type="password"/></div>
<div>
<button type="submit">Login</button>
</div>
<div th:if="${loginError}"><p>Invalid username or password</p></div>
</form>
</div>
</body>
</html>
Security config:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private PasswordEncoder passwordEncoder;
//TODO: fix this
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/welcome")
.failureUrl("/login-error")
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user").password("password").roles("USER");
}
#Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Login controller:
#Controller("login")
public class LoginController {
#GetMapping
public String login() {
return "login";
}
#PostMapping
public String postLogin() {
// TODO
return "/welcome";
}
#GetMapping("/login-error")
public String loginError(Model model) {
model.addAttribute("loginError", true);
return "login";
}
}
Response headers:
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Language:en-US
Content-Type:text/css;charset=UTF-8
Date:Thu, 23 Nov 2017 17:17:59 GMT
Expires:0
Pragma:no-cache
Transfer-Encoding:chunked
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
UPD:
An important thing to notice is that if I don't explisitly use permitAll() on /css/**, then I get 302 and redirect to login page. If I do, then I get 200 and content of login page in response body instead of actual content of css file
UPD 2:
Debug logs from spring security during request to login page, which should have the styles:
2017-11-24 17:43:33.926 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-11-24 17:43:33.927 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-11-24 17:43:33.938 DEBUG 4088 --- [io-1488-exec-10] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2017-11-24 17:43:33.938 DEBUG 4088 --- [io-1488-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-11-24 17:43:33.941 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-11-24 17:43:33.942 DEBUG 4088 --- [io-1488-exec-10] 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#f14213c
2017-11-24 17:43:33.942 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2017-11-24 17:43:33.943 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /logout
2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /login
2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-11-24 17:43:33.944 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-11-24 17:43:33.946 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-11-24 17:43:33.947 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2017-11-24 17:43:33.947 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-11-24 17:43:33.947 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.session.SessionManagementFilter : Requested session ID 3A4BF8C25F0B7B63F9906222B94C800A is invalid.
2017-11-24 17:43:33.948 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-11-24 17:43:33.948 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-11-24 17:43:33.950 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /login; Attributes: [permitAll]
2017-11-24 17:43:33.955 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#7f46f895, returned: 1
2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-11-24 17:43:33.963 DEBUG 4088 --- [io-1488-exec-10] o.s.security.web.FilterChainProxy : /login reached end of additional filter chain; proceeding with original chain
2017-11-24 17:43:34.826 DEBUG 4088 --- [io-1488-exec-10] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2017-11-24 17:43:34.862 DEBUG 4088 --- [io-1488-exec-10] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-11-24 17:43:34.862 DEBUG 4088 --- [io-1488-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2017-11-24 17:43:35.015 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-11-24 17:43:35.015 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-11-24 17:43:35.015 DEBUG 4088 --- [nio-1488-exec-9] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#7582e3b6. A new one will be created.
2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] 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#f14213c
2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /css/login.css' doesn't match 'POST /logout
2017-11-24 17:43:35.016 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /css/login.css' doesn't match 'POST /login
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#6fa8940c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: EACE11EC21F40FE5BD10CC56F71C0DD3; Granted Authorities: ROLE_ANONYMOUS'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-11-24 17:43:35.017 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/css/login.css'; against '/css/**'
2017-11-24 17:43:35.019 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /css/login.css; Attributes: [permitAll]
2017-11-24 17:43:35.019 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#6fa8940c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: EACE11EC21F40FE5BD10CC56F71C0DD3; Granted Authorities: ROLE_ANONYMOUS
2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#7f46f895, returned: 1
2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-11-24 17:43:35.021 DEBUG 4088 --- [nio-1488-exec-9] o.s.security.web.FilterChainProxy : /css/login.css reached end of additional filter chain; proceeding with original chain
2017-11-24 17:43:35.031 DEBUG 4088 --- [nio-1488-exec-9] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2017-11-24 17:43:35.033 DEBUG 4088 --- [nio-1488-exec-9] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-11-24 17:43:35.033 DEBUG 4088 --- [nio-1488-exec-9] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
UPD 3:
Debug logs of MVC seem fishy, why does it map the request to login.css to my login controller?
2017-11-24 19:05:13.967 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/css/login.css]
2017-11-24 19:05:13.967 DEBUG 27408 --- [nio-1488-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /css/login.css
2017-11-24 19:05:13.968 DEBUG 27408 --- [nio-1488-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String zhi.yest.furniture.controller.LoginController.login()]
2017-11-24 19:05:13.968 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/css/login.css] is: -1
2017-11-24 19:05:13.969 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/css] based on Accept header types and producible media types [*/*])
2017-11-24 19:05:13.969 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.servlet.view.BeanNameViewResolver : Found matching bean for view name 'login' - to be ignored since it does not implement View
2017-11-24 19:05:13.969 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.servlet.view.BeanNameViewResolver : No matching bean found for view name 'login.css'
2017-11-24 19:05:13.970 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.s.v.ContentNegotiatingViewResolver : No acceptable view found; returning null
2017-11-24 19:05:13.970 DEBUG 27408 --- [nio-1488-exec-9] o.s.w.servlet.view.BeanNameViewResolver : Found matching bean for view name 'login' - to be ignored since it does not implement View
2017-11-24 19:05:13.970 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet : Rendering view [org.thymeleaf.spring4.view.ThymeleafView#6cb35f4f] in DispatcherServlet with name 'dispatcherServlet'
2017-11-24 19:05:13.979 DEBUG 27408 --- [nio-1488-exec-9] o.s.web.servlet.DispatcherServlet : Successfully completed request
First try setting property for debug mode logging and verify it but i'm quite sure it's because you are trying to get resource as anonymous user, try replacing .permitAll() with .anonymous()
Try to override the configure(WebSecurity web) method in your SecurityConfig.
Also, you can try to change in configure(HttpSecurity http) the paths of the static folders (so you will be able to have an access to them from thymeleaf templates with #{/css/main.css}):
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private PasswordEncoder passwordEncoder;
// fix this
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/static/**", "/resources/templates/**");
}
// fix this
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/css/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/welcome")
.failureUrl("/login-error")
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user").password("password").roles("USER");
}
#Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
I am trying to log messages after a successful/failed login/logout in Spring Security.
Also, I'm using Spring Boot, so there is little configuration code.
The form that I am using is auto-generated.
WebSecurityConfig.java
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin();
}
#Configuration
protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {
#Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userSearchFilter("(uid={0})")
.contextSource()
.url("ldap://...:389/ou=...,dc=...,dc=...")
.managerDn("cn=...,dc=...,dc=...")
.managerPassword("...");
}
}
}
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
</configuration>
My code for login success is as follows:
LoginSuccessService.java
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.*;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
#Component
public class LoginSuccessService implements ApplicationListener<InteractiveAuthenticationSuccessEvent>{
private static final Logger logger = LoggerFactory.getLogger(LoginSuccessService.class);
#Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
logger.debug("You have been logged in successfully.");
Date loginDate = new Date();
logger.debug("Login Time: " + loginDate.toString());
}
}
It won't work. I get nothing in the log.
What additional code do I need to write, if any? Do I need to initialize this listener anywhere?
I also used this link as reference, but I figured I didn't need to write a publisher, as I am not writing my own class for the event.
I have also tried with AuthenticationSuccessEvent instead of InteractiveAuthenticationSuccessEvent, but same thing.
If it helps, a failed login produces the following output(expected output should include "Failed to log in" and the current date, this is a log with debug=TRUE in application.properties):
2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.c.web.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#67a404ea
2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /login at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /login at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-03-16 18:50:12.779 DEBUG 8895 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#56979972: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#56979972: Principal: org.springframework.security.ldap.userdetails.LdapUserDetailsImpl#a96aab26: Dn: cn=User,ou=users,dc=vs,dc=local; Username: user; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; CredentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 524F4F9744824535095B43C18FBA71F4; Not granted any authorities'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /login at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] 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#3a3c5471
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /login at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /login at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/logout'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /login at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/login'
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.l.a.LdapAuthenticationProvider : Processing authentication request for user: iprnein
2016-03-16 18:50:12.780 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.l.s.FilterBasedLdapUserSearch : Searching for user 'iprnein', with user search [ searchFilter: '(uid={0})', searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
2016-03-16 18:50:12.781 DEBUG 8895 --- [nio-8080-exec-7] o.s.l.c.support.AbstractContextSource : Got Ldap context on server 'ldap://192.168.10.41:389/ou=users,dc=vs,dc=local'
2016-03-16 18:50:12.788 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.ldap.SpringSecurityLdapTemplate : Searching for entry under DN 'ou=users,dc=vs,dc=local', base = '', filter = '(uid={0})'
2016-03-16 18:50:12.789 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'loginFailureService'
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'delegatingApplicationListener'
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.a.UsernamePasswordAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler#19d8353
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] o.s.s.web.DefaultRedirectStrategy : Redirecting to '/login?error'
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-03-16 18:50:12.790 DEBUG 8895 --- [nio-8080-exec-7] o.s.b.c.web.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#67a404ea
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.b.c.web.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#67a404ea
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login?error at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login?error at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#68e82290. A new one will be created.
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login?error at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] 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#3a3c5471
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login?error at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login?error at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /logout
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login?error at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /login
2016-03-16 18:50:12.800 DEBUG 8895 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login?error at position 7 of 13 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2016-03-16 18:50:12.801 DEBUG 8895 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-03-16 18:50:12.801 DEBUG 8895 --- [nio-8080-exec-9] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-03-16 18:50:12.801 DEBUG 8895 --- [nio-8080-exec-9] o.s.b.c.web.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#67a404ea
The error turned out to be configuration-related.
For capturing login events, I used the objects
InteractiveAuthenticationSuccessEvent or
AuthenticationSuccessEvent(logout doesn't have an implemented listener yet, you might have luck with HttpSessionEvent).
Also, it's important to see whether or not the logger is configured to log your package; the application is not configured by default to log application messages. That is why I was not getting any output.
So, two things:
If your package name is com.mycompany, you should add a line in your application.properties or application.yml file(usually found in <PROJ_DIR>/src/main/resources/; if not, create your own) for logging:
application.properties:
logging.level.com.mycompany=DEBUG/INFO/WARN/ERROR
#debug is lowest, error is highest
or:
application.yml:
logging:
level:
com:
mycompany: DEBUG/INFO/WARN/ERROR
If you are trying to log an outside package, log it with the debug() method or it might not show up(I used info() and I got nothing).
I am using java config in spring boot, spring security application. I have configured the error controller as below. But whenever, I enter an invalid URL it goes to error.jsp, which is configured to handle the errors in the application:
#Controller
public class AppErrorController implements ErrorController {
private static final String PATH = "/error";
#RequestMapping(value = "/pageNotFound", method = { RequestMethod.GET, RequestMethod.POST })
public String pageNotFound() {
return "pageNotFound";
}
#RequestMapping(value = "/accessDenied", method = { RequestMethod.GET, RequestMethod.POST })
public String accessDenied() {
return "accessDenied";
}
#RequestMapping(value = PATH)
public String error() {
return "error";
}
#Override
public String getErrorPath() {
return PATH;
}
}
web.xml
<error-page>
<error-code>404</error-code>
<location>/pageNotFound</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error</location>
</error-page>
404 is never thrown when the invalid URL is entered.
Also, I am not using embedded tomcat. I am deploying war to the external tomcat. I have this in my application.yml file:
server:
error:
whitelabel:
enabled: false
Below is the log in case if I enter a invalid URL. There is no error. It just redirects to /error in case of invalid URL:
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.b.c.web.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#371ef2a3
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/donotexisturl'; against '/static/**'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/donotexisturl'; against '/i18n/**'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#b8db0c9d: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='adam.milne#abcd.com', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] 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#6e929f31
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /donotexisturl' doesn't match 'POST /logout
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-03-15 10:02:45.061 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /donotexisturl' doesn't match 'POST /checklogin
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 7 of 13 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken#b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='adam.milne#abcd.com', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /donotexisturl' doesn't match 'POST /logout
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/donotexisturl'; against '/login**'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/donotexisturl'; against '/error**'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/donotexisturl'; against '/checklogin**'
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /doNotExistURL; Attributes: [fullyAuthenticated]
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='adam.milne#abcd.com', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.access.vote.UnanimousBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#6ad88564, returned: 1
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.access.vote.UnanimousBased : Voter: org.springframework.security.access.vote.AuthenticatedVoter#19007bb6, returned: 0
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.access.vote.UnanimousBased : Voter: com.sts.app.core.user.security.AccessDecisionVoterImpl#1465b821, returned: 1
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /doNotExistURL reached end of additional filter chain; proceeding with original chain
2016-03-15 10:02:45.062 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/gen/doNotExistURL]
2016-03-15 10:02:45.063 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /doNotExistURL
2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/doNotExistURL]
2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/doNotExistURL] are [/**]
2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/doNotExistURL] are {}
2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/doNotExistURL] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#87dd2cb]]] and 1 interceptor
2016-03-15 10:02:45.064 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/gen/doNotExistURL] is: -1
2016-03-15 10:02:45.077 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet : Successfully completed request
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.b.c.web.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#371ef2a3
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.b.c.web.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.core.ApplicationHttpRequest#20ae74b1
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/error'; against '/static/**'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/error'; against '/i18n/**'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#b8db0c9d: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='adam.milne#abcd.com', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /error' doesn't match 'POST /logout
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 6 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-03-15 10:02:45.078 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /error' doesn't match 'POST /checklogin
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 7 of 13 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken#b8db0c9d: Principal: User{id=8, firstname='Adam', lastname='Milne', email='adam.milne#abcd.com', roleId=1}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffd148a: RemoteIpAddress: 127.0.0.1; SessionId: FED1F23633671F6E257CA9C5AFCEE216; Granted Authorities: ModuleOperation{moduleOperationId=1, moduleOperationName='roleList', moduleId=2, moduleName='role'}, ModuleOperation{moduleOperationId=8, moduleOperationName='deleteUser', moduleId=1, moduleName='user'}'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.security.web.FilterChainProxy : /error reached end of additional filter chain; proceeding with original chain
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/gen/error]
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2016-03-15 10:02:45.079 DEBUG 9997 --- [io-8080-exec-22] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String com.sts.app.core.common.web.AppErrorController.error()]
First off, define an exception for each especial HTTP error you're going to handle. Here i'm just defining one for handling 404 Not Found case:
public class NotFoundException extends RuntimeException {}
To replace the default Spring Boot's error handling mechanism completely, we can implement ErrorController. Instead of just implementing the ErrorController, here i'm extending AbstractErrorController, which implements the ErrorController and provides some auxiliary methods like getStatus().
Anyway, the basic idea is to handle all errors using an endpoint, say /error, and throw those pre-defined exceptions in case of their corresponding HTTP status codes:
#Controller
public class CustomErrorController extends AbstractErrorController {
private static final String ERROR_PATH= "/error";
#Autowired
public CustomErrorController(ErrorAttributes errorAttributes) {
super(errorAttributes);
}
/**
* Just catching the {#linkplain NotFoundException} exceptions and render
* the 404.jsp error page.
*/
#ExceptionHandler(NotFoundException.class)
public String notFound() {
return "404";
}
/**
* Responsible for handling all errors and throw especial exceptions
* for some HTTP status codes. Otherwise, it will return a map that
* ultimately will be converted to a json error.
*/
#RequestMapping(ERROR_PATH)
public ResponseEntity<?> handleErrors(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status.equals(HttpStatus.NOT_FOUND))
throw new NotFoundException();
return ResponseEntity.status(status).body(getErrorAttributes(request, false));
}
#Override
public String getErrorPath() {
return ERROR_PATH;
}
}
Of course, this solution is only suitable for Traditional Deployment. If you're planning to use an Embedded Servlet Container, you're better off defining an EmbeddedServletContainerCustomizer.
Whould you like to add this #Bean to your spring application config, like this :
#Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error404.html");
container.addErrorPages(error404Page);
}
};
}
and put error404.html in your static folder.
Reference :
http://www.sporcic.org/2014/05/custom-error-pages-with-spring-boot/
Here you go
#RestController
public class RestErrorController implements ErrorController{
private static final String PATH = "/error";
#Autowired
private ErrorAttributes errorAttributes;
#RequestMapping(value=PATH,method=RequestMethod.GET)
public ApiErrorExtended error(HttpServletRequest request, HttpServletResponse response){
return new ApiErrorExtended( response.getStatus(),getErrorAttributes(request, true));
}
private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
RequestAttributes requestAttributes = new ServletRequestAttributes(request);
return errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
}
public String getErrorPath() {
return PATH;
}
}
This is my rest error controller. You can modify it to return whatever u want.
hi,you only need to configure the following:
<error-page>
<error-code>404</error-code>
<location>/pageNotFound/404.jsp</location>
</error-page>
and you configure the Java exception:
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/pageNotFound/exception.jsp</location>