Spring security 403 response on POST\PUT\DELETE - java

I'm trying to get some Role-based authorization working on spring, but I have trouble with 403 responses on POST\PUT\DELETE requests. I've been looking for solutions elsewhere but provided solutions with disabling csrf do not solve the issue.
This is my HTTP config:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.PATCH, "/user/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.PUT, "/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.POST, "/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.antMatchers(HttpMethod.DELETE,"/**").hasAnyRole("ROLE_TRAINER", "ROLE_ADMIN")
.anyRequest().authenticated()
.and()
.csrf().disable()
.formLogin().permitAll()
.and()
.logout().permitAll();
}
When I debug my code, only GET requests make my program go through the UserDetails objects to provide the Roles collection (as defined below)
public class BrevisFitUser extends User implements UserDetails {
public BrevisFitUser(final User user) {
super(user);
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles()
.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName().toUpperCase()))
.collect(Collectors.toList());
}
On a PUT request for instance, this is the log I get:
2019-11-20 13:28:47.560 DEBUG 15456 --- [nio-8080-exec-5] o.a.coyote.http11.Http11InputBuffer : Received [PUT /exercise/strap/3 HTTP/1.1
Content-Type: application/json
Authorization: Basic c2ltb24ua25lejpzaW1vbi5rbmV6
User-Agent: PostmanRuntime/7.19.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 7a829877-6de4-4746-8e27-63677f0160d2
Host: localhost:8080
Accept-Encoding: gzip, deflate
Content-Length: 75
Cookie: JSESSIONID=45F53EE556C13E672E6ECFD5865B5FD6
Connection: keep-alive
{
"unitLength": 29,
"name": "Yellow strap home marked smaller"
}]
2019-11-20 13:28:47.560 DEBUG 15456 --- [nio-8080-exec-5] o.a.t.util.http.Rfc6265CookieProcessor : Cookies: Parsing b[]: JSESSIONID=45F53EE556C13E672E6ECFD5865B5FD6
2019-11-20 13:28:47.561 DEBUG 15456 --- [nio-8080-exec-5] o.a.catalina.connector.CoyoteAdapter : Requested cookie session id is 45F53EE556C13E672E6ECFD5865B5FD6
2019-11-20 13:28:47.561 DEBUG 15456 --- [nio-8080-exec-5] o.a.c.authenticator.AuthenticatorBase : Security checking request PUT /exercise/strap/3
2019-11-20 13:28:47.561 DEBUG 15456 --- [nio-8080-exec-5] org.apache.catalina.realm.RealmBase : No applicable constraints defined
2019-11-20 13:28:47.562 DEBUG 15456 --- [nio-8080-exec-5] o.a.c.authenticator.AuthenticatorBase : Not subject to any constraint
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#e2265dfb: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#e2265dfb: Principal: com.brevisfit.api.model.user.User[ iduser=1 ]; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 45F53EE556C13E672E6ECFD5865B5FD6; Granted Authorities: ROLE_ADMIN, ROLE_TRAINER'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-11-20 13:28:47.563 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /exercise/strap/3 at position 4 of 15 in additional filter chain; firing Filter: 'CsrfFilter'
2019-11-20 13:28:47.564 DEBUG 15456 --- [nio-8080-exec-5] org.apache.tomcat.util.http.Parameters : Set encoding to UTF-8
2019-11-20 13:28:47.564 DEBUG 15456 --- [nio-8080-exec-5] o.s.security.web.csrf.CsrfFilter : Invalid CSRF token found for http://localhost:8080/exercise/strap/3
2019-11-20 13:28:47.564 DEBUG 15456 --- [nio-8080-exec-5] 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#25ff6f87
2019-11-20 13:28:47.565 DEBUG 15456 --- [nio-8080-exec-5] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Based on the issue with the csrf, I have added the following code to the configuration:
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null
&& !token.equals(cookie.getValue())) {
// Token is being added to the XSRF-TOKEN cookie.
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
And have tried with removal of antMatchers and just require authenticationi:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().httpBasic()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class); // Register csrf filter.
}
Any idea, why such behaviour?

Related

User is anonymous even after successful login

After logging in successfully via POST /api/v1/auth/login, subsequent requests to GET /api/v1/userAccounts/me are considered to be anonymous according to Spring Security.
This is my security config:
#Configuration
#EnableGlobalMethodSecurity(
prePostEnabled = true,
securedEnabled = true,
jsr250Enabled = true
)
#Order(1)
#RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsServiceImpl userDetailsService;
private final Config config;
private final ObjectMapper objectMapper;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.antMatchers(
"/api/v1/auth/**",
"/api/v1/reference/**"
)
.permitAll()
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.successHandler((request, response, authentication) -> {
response.getWriter().append("OK");
response.setStatus(HttpServletResponse.SC_OK);
})
.failureHandler((request, response, exception) -> {
response.getWriter().append("Invalid credentials or inactive account");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
})
.loginProcessingUrl("/api/v1/auth/login")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/api/v1/auth/logout", "POST"))
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler((request, response, accessDeniedException) -> {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
objectMapper.writeValue(
response.getWriter(),
ErrorResponseBody
.builder()
.code(ErrorType.ACCESS_DENIED)
.status(HttpServletResponse.SC_FORBIDDEN)
.message("Access denied")
.build()
);
})
.authenticationEntryPoint((request, response, authException) -> {
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
objectMapper.writeValue(
response.getWriter(),
ErrorResponseBody
.builder()
.code(ErrorType.LOGIN_REQUIRED)
.status(HttpServletResponse.SC_UNAUTHORIZED)
.message("You are not authorized to access this resource")
.build()
);
})
.and()
.userDetailsService(userDetailsService);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public CorsConfigurationSource corsConfigurationSource() {
final var configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(config.getAllowedOrigins());
configuration.setAllowedMethods(asList("GET", "POST", "PUT", "PATCH", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList(HttpHeaders.AUTHORIZATION, HttpHeaders.CACHE_CONTROL, HttpHeaders.CONTENT_TYPE, HttpHeaders.ACCEPT));
final var source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", configuration);
return source;
}
}
Here's the debug logging from the form login request:
2020-11-25 22:41:27.017 DEBUG 74979 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /api/v1/auth/login at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-11-25 22:41:27.017 DEBUG 74979 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /api/v1/auth/login at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-11-25 22:41:27.017 DEBUG 74979 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2020-11-25 22:41:27.017 DEBUG 74979 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /api/v1/auth/login at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /api/v1/auth/login at position 4 of 12 in additional filter chain; firing Filter: 'CorsFilter'
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /api/v1/auth/login at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/v1/auth/login'; against '/api/v1/auth/logout'
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /api/v1/auth/login at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/v1/auth/login'; against '/api/v1/auth/login'
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
2020-11-25 22:41:27.018 DEBUG 74979 --- [nio-8080-exec-9] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2020-11-25 22:41:27.145 DEBUG 74979 --- [nio-8080-exec-9] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy#454043bf
2020-11-25 22:41:27.145 DEBUG 74979 --- [nio-8080-exec-9] w.a.UsernamePasswordAuthenticationFilter : Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#1fcaf72e: Principal: com.example.server.security.UserDetailsServiceImpl$UserDetailsImpl#3bd8fbc9; 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: ONBOARD
2020-11-25 22:41:27.145 DEBUG 74979 --- [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#2e14ccb
2020-11-25 22:41:27.145 DEBUG 74979 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : HttpSession being created as SecurityContext is non-default
2020-11-25 22:41:27.145 DEBUG 74979 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl#1fcaf72e: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#1fcaf72e: Principal: com.example.server.security.UserDetailsServiceImpl$UserDetailsImpl#3bd8fbc9; 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: ONBOARD' stored to HttpSession: 'org.apache.catalina.session.StandardSessionFacade#481bcf3f
2020-11-25 22:41:27.145 DEBUG 74979 --- [nio-8080-exec-9] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
and the logs from the GET /api/v1/userAccounts/me request which follows:
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#6384c25. A new one will be created.
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 4 of 12 in additional filter chain; firing Filter: 'CorsFilter'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /api/v1/userAccounts/me' doesn't match 'POST /api/v1/auth/logout'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /api/v1/userAccounts/me' doesn't match 'POST /api/v1/auth/login'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : pathInfo: both null (property equals)
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : queryString: both null (property equals)
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : requestURI: arg1=/api/v1/userAccounts/me; arg2=/api/v1/userAccounts/me (property equals)
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : serverPort: arg1=8080; arg2=8080 (property equals)
2020-11-25 22:41:27.198 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : requestURL: arg1=http://localhost:8080/api/v1/userAccounts/me; arg2=http://localhost:8080/api/v1/userAccounts/me (property equals)
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : scheme: arg1=http; arg2=http (property equals)
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : serverName: arg1=localhost; arg2=localhost (property equals)
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : contextPath: arg1=; arg2= (property equals)
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.DefaultSavedRequest : servletPath: arg1=/api/v1/userAccounts/me; arg2=/api/v1/userAccounts/me (property equals)
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.s.HttpSessionRequestCache : Removing DefaultSavedRequest from session if present
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#4c26704b: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 4ED2DAB934C3163D40A9FE32EFE26A2A; Granted Authorities: ROLE_ANONYMOUS'
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-11-25 22:41:27.199 DEBUG 74979 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /api/v1/userAccounts/me at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-11-25 22:41:27.200 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /api/v1/userAccounts/me' doesn't match 'POST /api/v1/auth/logout'
2020-11-25 22:41:27.200 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/v1/userAccounts/me'; against '/api/v1/auth/**'
2020-11-25 22:41:27.200 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/v1/userAccounts/me'; against '/api/v1/reference/**'
2020-11-25 22:41:27.200 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/v1/userAccounts/me; Attributes: [authenticated]
2020-11-25 22:41:27.200 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#4c26704b: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 4ED2DAB934C3163D40A9FE32EFE26A2A; Granted Authorities: ROLE_ANONYMOUS
2020-11-25 22:41:27.200 DEBUG 74979 --- [io-8080-exec-10] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#1970e63, returned: -1
2020-11-25 22:41:27.201 DEBUG 74979 --- [io-8080-exec-10] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
Any idea why the request is being considered anonymous?

Spring Security OAuth2 grants a token, then immediately can't remember it: Access is denied (user is anonymous)

I get a token
$ curl -u badge:123456 http://localhost:8080/oauth/token -d grant_type=password -d username=admin -d password=admin -d client_id=badge -d client_secret=123456 -d scope=write
{"access_token":"00a872f9-6f6e-4073-af17-d07d3991c2f0","token_type":"bearer","refresh_token":"8772d67c-682a-4b56-ae51-5a4bc4dceff7","expires_in":43199,"scope":"write"}
Then immediately try to use it
$ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer 00a872f9-6f6e-4073-af17-d07d3991c2f0" -d '{"apiKey": "key", "tag": "tag"}' localhost:8080/isTagAvailable
But it says I'm anonymous!
2018-05-26 23:43:28.390 DEBUG 54284 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : /isTagAvailable at position 7 of 10 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2018-05-26 23:43:28.391 DEBUG 54284 --- [nio-8080-exec-5] 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'
Why?
OAuth2Configurtion.java
#Configuration
#EnableAuthorizationServer
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient(applicationName)
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.authorities("ROLE_USER")
// .scopes("read", "write")
.scopes("write")
.resourceIds(applicationName)
.secret("123456");
}
SecurityConfig.java
#Configuration
#EnableWebSecurity//(debug=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/isTagAvailable").authenticated()
.and()
.authorizeRequests()
.antMatchers("/robots.txt", "/error", "/login", "/doLogout", "/home", "/pageNotFound"
).permitAll()
.and()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable()
.httpBasic().disable();
}
Version
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
I added
.anonymous().disable()
But now it gives
2018-05-27 00:42:54.987 DEBUG 54284 --- [nio-8080-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/isTagAvailable'; against '/isTagAvailable'
2018-05-27 00:42:54.987 DEBUG 54284 --- [nio-8080-exec-2] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /isTagAvailable; Attributes: [authenticated]
2018-05-27 00:42:54.988 DEBUG 54284 --- [nio-8080-exec-2] o.s.s.w.a.ExceptionTranslationFilter : Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
It still can't remember the token!
I threw away #EnableWebSecurity and WebSecurityConfigurerAdapter which just totally breaks the app. I thought they were required to get access to HttpSecurity which I thought I needed. I discovered this simple new class will solve the problem.
#Configuration
#EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
String [] ignoredPaths = new String[]{...};
#Override
public void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.antMatchers(ignoredPaths).permitAll()
.anyRequest().authenticated()
.and()
.httpBasic();
}

Extending SimpleUrlAuthenticationFailureHandler produces 404 with No mapping found warning

I am trying to extend SimpleUrlAuthenticationFailureHandler to achieve some custom functionality upon authentication failure in spring security. All of my config is in java code so there is no security xml files, etc. the code for CustomAuthenticationFailureHandler is as below;
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler{
public CustomAuthenticationFailureHandler(String defaultFailureUrl) {
super(defaultFailureUrl);
}
#Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
String userName = request.getParameter("username");
System.out.println("Invalid login attempt by user " + userName);
// This performs custom auditing upon each login failure
userLogRepository.logUserActivity(userName, -1, request.getRemoteHost(), exception);
super.onAuthenticationFailure(request, response, exception);
}
}
and this handler is applied to the spring security as below;
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
#Qualifier("userDetailsService")
UserDetailsService userDetailsService;
#Autowired
#Qualifier("userLogRepository")
UserLogRepository userLogRepository;
#Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
CsrfTokenResponseHeaderBindingFilter csrfTokenFilter = new CsrfTokenResponseHeaderBindingFilter();
http.addFilterAfter(csrfTokenFilter, CsrfFilter.class);
http.authorizeRequests().antMatchers("/rest/**").access("hasRole('ROLE_REST_USER')")
.and().formLogin().successHandler(new CustomLoginSuccessHandler(new AjaxAuthenticationSuccessHandler(new SavedRequestAwareAuthenticationSuccessHandler())))
// If I use the following failureUrl method it all seems to work correctly but then I don't have the custom implementaiton.
//.failureUrl("/login?error=1").permitAll()
.failureHandler(new CustomAuthenticationFailureHandler("/login?error=1"))
.and().logout().invalidateHttpSession(true).addLogoutHandler(new CustomLogoutSuccessHandler()).permitAll()
.and().exceptionHandling().accessDeniedPage("/403")
.and().csrf();
}
I have put the org.springframework.security package in debug mode logging for both config 1) using the failureUrl and 2) using custom failure handler. In the below log snippets the DefaultLoginPageGeneratingFilter seems to redirect correctly to "/login?error=1" if the failureUrl configuration is use.
Using failureUrl method (This works)
2016-10-06 15:43:24,839 [http-bio-8080-exec-5 : DEBUG] SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error=1
2016-10-06 15:43:24,839 [http-bio-8080-exec-5 : DEBUG] DefaultRedirectStrategy : Redirecting to '/web-console/login?error=1'
2016-10-06 15:43:24,840 [http-bio-8080-exec-5 : DEBUG] HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#798d735c
2016-10-06 15:43:24,840 [http-bio-8080-exec-5 : DEBUG] HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-10-06 15:43:24,840 [http-bio-8080-exec-5 : DEBUG] SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-10-06 15:43:24,843 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-10-06 15:43:24,843 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#4ef1ae10. A new one will be created.
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 4 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 5 of 14 in additional filter chain; firing Filter: 'CsrfTokenResponseHeaderBindingFilter'
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 6 of 14 in additional filter chain; firing Filter: 'LogoutFilter'
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /logout
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 7 of 14 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /login
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] FilterChainProxy : /login?error=1 at position 8 of 14 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#798d735c
2016-10-06 15:43:24,844 [http-bio-8080-exec-6 : DEBUG] HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-10-06 15:43:24,845 [http-bio-8080-exec-6 : DEBUG] SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Using Custom failure handler (This doesn't work)
2016-10-06 15:37:20,413 [http-bio-8080-exec-6 : DEBUG] DefaultRedirectStrategy : Redirecting to '/web-console/login?error=1'
2016-10-06 15:37:20,413 [http-bio-8080-exec-6 : DEBUG] HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#26019c88
2016-10-06 15:37:20,414 [http-bio-8080-exec-6 : DEBUG] HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-10-06 15:37:20,414 [http-bio-8080-exec-6 : DEBUG] SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-10-06 15:37:20,417 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-10-06 15:37:20,417 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-10-06 15:37:20,417 [http-bio-8080-exec-7 : DEBUG] HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-10-06 15:37:20,417 [http-bio-8080-exec-7 : DEBUG] HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#58e4d010. A new one will be created.
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 4 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 5 of 14 in additional filter chain; firing Filter: 'CsrfTokenResponseHeaderBindingFilter'
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 6 of 14 in additional filter chain; firing Filter: 'LogoutFilter'
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /logout
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 7 of 14 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /login
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 8 of 14 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 9 of 14 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] DefaultSavedRequest : pathInfo: both null (property equals)
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] DefaultSavedRequest : queryString: arg1=null; arg2=error=1 (property not equals)
2016-10-06 15:37:20,418 [http-bio-8080-exec-7 : DEBUG] HttpSessionRequestCache : saved request doesn't match
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 10 of 14 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 11 of 14 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] 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: 99432565D3173E5497B49BC0DF428692; Granted Authorities: ROLE_ANONYMOUS'
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 12 of 14 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 13 of 14 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 at position 14 of 14 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] AntPathRequestMatcher : Request 'GET /login' doesn't match 'POST /logout
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] AntPathRequestMatcher : Checking match of request : '/login'; against '/rest/**'
2016-10-06 15:37:20,419 [http-bio-8080-exec-7 : DEBUG] FilterSecurityInterceptor : Public object - authentication not attempted
2016-10-06 15:37:20,420 [http-bio-8080-exec-7 : DEBUG] FilterChainProxy : /login?error=1 reached end of additional filter chain; proceeding with original chain
I have only attached relevant log snippets as the debug mode has produce a lot of logs which I don't think are relevant, however do let me know if required any I can add more.
I am not sure if I am missing something in configuration here. Would someone please advice me how should I approach the failure url redirection scenario while using the custom failure handler?
As mentioned in one of the comments using custom login form has worked even if the login page is the same name as default i.e. /login. Looking at the code of DefaultLoginPageGeneratingFilter it only sets the logout and failure url if failure handler is not used. My working WebSecurityConfigurerAdapter config looks like as below;
#Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)/*.passwordEncoder(new BCryptPasswordEncoder())*/;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(csrfTokenFilter, CsrfFilter.class);
http.authorizeRequests().antMatchers("/rest/**").access("hasRole('ROLE_REST_USER')")
.and().formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password").permitAll()
.successHandler(loginSuccessHandler)
.failureHandler(authenticationFailureHandler).permitAll()
.and().logout().invalidateHttpSession(true).addLogoutHandler(logoutSuccessHandler).permitAll()
.and().exceptionHandling().accessDeniedPage("/403")
.and().csrf();
}

404 error page configuration with Spring 4 annotations

I have a Spring MVC project with Spring 4. My server is tomcat 7.
I'm trying to make a 404 page, I tried many things, but I couldn't do that.
What am I missing?
Here is WebAppContext :
#Configuration
#ComponentScan(basePackages = {
"com.***"
})
#EnableWebMvc
public class WebAppContext extends WebMvcConfigurerAdapter {
private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/pages/";
private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
#Autowired
private EventLogService eventLogService;
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public SimpleMappingExceptionResolver exceptionResolver() {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
Properties exceptionMappings = new Properties();
exceptionMappings.put("org.springframework.security.web.authentication.rememberme.CookieTheftException", "user/login?error=sessionExpired");
exceptionMappings.put("java.lang.RuntimeException", "error/error");
exceptionMappings.put("java.lang.Exception", "error/error");
exceptionResolver.setExceptionMappings(exceptionMappings);
Properties statusCodes = new Properties();
statusCodes.put("error/403", "403");
statusCodes.put("error/404", "404");
statusCodes.put("error/error", "500");
exceptionResolver.setStatusCodes(statusCodes);
return exceptionResolver;
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);
return viewResolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
registry.addInterceptor(new EventLogInterceptor(eventLogService)).addPathPatterns("/xyz/{urlText}");
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor localeChangeInterceptor=new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(new Locale("en"));
return cookieLocaleResolver;
}
}
Here is my security config
#Override
protected void configure(HttpSecurity http) throws Exception {
http
//Configures form login
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login/authenticate")
.failureUrl("/login?error=bad_credentials")
.and()
.exceptionHandling().accessDeniedPage("/403")
//Configures the logout function
.and()
.logout()
.deleteCookies("JSESSIONID")
.logoutUrl("/logout")
.logoutSuccessUrl("/")
//Configures url based authorization
.and()
.authorizeRequests()
//Anyone can access the urls
.antMatchers(
"/auth/**",
"/signin",
"/login",
"/feedback",
"/signup/**",
"/user/forgotPass/**"
).permitAll()
.antMatchers(
"/user/settings/**"
).authenticated()
.antMatchers(
"/report/**"
).hasAnyRole("ADMIN")
.antMatchers("/manage/**"
).hasAnyRole("ADMIN", "EDITOR")
.and()
.rememberMe().rememberMeServices(springSocialSecurityRememberMeServices())
.key("MyRememberMe")
.and()
.apply(new SpringSocialConfigurer());
}
Application Config:
public class ApplicationConfig implements WebApplicationInitializer {
private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
private static final String DISPATCHER_SERVLET_MAPPING = "/";
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ApplicationContext.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING);
EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("characterEncoding", characterEncodingFilter);
characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
FilterRegistration.Dynamic security = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
security.addMappingForUrlPatterns(dispatcherTypes, true, "/*");
servletContext.addListener(new ContextLoaderListener(rootContext));
}
}
My page is at /src/main/webapp/WEB-INF/pages/error/404.jsp location.
I get this error page, when I try a random url:
Here is the log file:
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2015-09-01 09:25:05 DEBUG HttpSessionSecurityContextRepository:167 - Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#44339553: Authentication: org.springframework.security.authentication.RememberMeAuthenticationToken#44339553: Principal: com.**#2e96279e[id=10,username=**,firstName=**,lastName=**,role=ROLE_USER,socialSignInProvider=<null>,profileImageUrl;=<null>]; 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_USER'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2015-09-01 09:25:05 DEBUG HstsHeaderWriter:129 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#a3c01f
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 4 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 5 of 14 in additional filter chain; firing Filter: 'LogoutFilter'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/logout'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 6 of 14 in additional filter chain; firing Filter: 'SocialAuthenticationFilter'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 7 of 14 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:127 - Request 'GET /test' doesn't match 'POST /login/authenticate
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 8 of 14 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 9 of 14 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 10 of 14 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
2015-09-01 09:25:05 DEBUG RememberMeAuthenticationFilter:142 - SecurityContextHolder not populated with remember-me token, as it already contained: 'org.springframework.security.authentication.RememberMeAuthenticationToken#44339553: Principal: com.**#2e96279e[id=10,username=**,firstName=**,lastName=**,role=ROLE_USER,socialSignInProvider=<null>,profileImageUrl;=<null>]; 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_USER'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 11 of 14 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2015-09-01 09:25:05 DEBUG AnonymousAuthenticationFilter:107 - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.RememberMeAuthenticationToken#44339553: Principal: com.**#2e96279e[id=10,username=**,firstName=**,lastName=**,role=ROLE_USER,socialSignInProvider=<null>,profileImageUrl;=<null>]; 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_USER'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 12 of 14 in additional filter chain; firing Filter: 'SessionManagementFilter'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 13 of 14 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2015-09-01 09:25:05 DEBUG FilterChainProxy:337 - /test at position 14 of 14 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/auth/**'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/signin'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/login'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/feedback'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/signup/**'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/user/forgotpass/**'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/user/activate/**'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/user/register/**'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/user/{username}/**'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/user/settings/**'
2015-09-01 09:25:05 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/test'; against '/report/**'
2015-09-01 09:25:05 DEBUG FilterSecurityInterceptor:185 - Public object - authentication not attempted
2015-09-01 09:25:05 DEBUG FilterChainProxy:323 - /test reached end of additional filter chain; proceeding with original chain
2015-09-01 09:25:05 DEBUG DispatcherServlet:845 - DispatcherServlet with name 'dispatcher' processing GET request for [/test]
2015-09-01 09:25:05 DEBUG RequestMappingHandlerMapping:297 - Looking up handler method for path /test
2015-09-01 09:25:05 DEBUG RequestMappingHandlerMapping:305 - Did not find handler method for [/test]
2015-09-01 09:25:05 DEBUG SimpleUrlHandlerMapping:169 - Matching patterns for request [/test] are [/**]
2015-09-01 09:25:05 DEBUG SimpleUrlHandlerMapping:194 - URI Template variables for request [/test] are {}
2015-09-01 09:25:05 DEBUG SimpleUrlHandlerMapping:124 - Mapping [/test] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#3396f11f] and 1 interceptor
2015-09-01 09:25:05 DEBUG DispatcherServlet:931 - Last-Modified value for [/test] is: -1
2015-09-01 09:25:05 DEBUG DispatcherServlet:1018 - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling
2015-09-01 09:25:05 DEBUG DispatcherServlet:991 - Successfully completed request
2015-09-01 09:25:05 DEBUG ExceptionTranslationFilter:115 - Chain processed normally
2015-09-01 09:25:05 DEBUG SecurityContextPersistenceFilter:97 - SecurityContextHolder now cleared, as request processing completed
This issue is related to Servlet 3 spec rather than Spring MVC 4. Although Servlet 3 provided a programatic mechanism to configure the web components (Servlets, Filters etc.), it is still not full fledged. There is a JIRA which explains this https://java.net/jira/browse/SERVLET_SPEC-50.
So, the solution is to add web.xml and configure error pages there in traditional way.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd"
version="3.0">
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/pages/error/404.jsp</location>
</error-page>
</web-app>

Spring security custom login form issue

When making post request to login controller url (/api/auth) I recieve index.html in response.
My security config:
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.
inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/assets/**","/index.html","/css/**","/js/**","/views/**","/bower_components/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/api/auth")
.permitAll().and().csrf().disable();
http.authorizeRequests().anyRequest().authenticated().and().csrf().disable();
}
}
My angular controller:
app.controller('LoginController', function ($rootScope, $scope, $http, $location) {
var authenticate = function (credentials, callback) {
var headers = credentials ? {authorization: "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};
credentials ? console.log(credentials.username + " " + credentials.password) : console.log("empty credentials")
//console.log(header);
$http.post('/#/api/auth', {"headers":headers}).success(function (data) {
if (data.name) {
$rootScope.authenticated = true;
console.log("in authenticate " + data.name)
} else {
$rootScope.authenticated = false;
console.log("in authenticate data in null")
}
callback && callback();
}).error(function () {
$rootScope.authenticated = false;
console.log("error in authenticate")
callback && callback();
});
}
authenticate();
$scope.credentials = {};
$scope.login = function () {
authenticate($scope.credentials, function () {
if ($rootScope.authenticated) {
$location.path("/");
console.log("in callback " + $scope.credentials)
$scope.error = false;
} else {
$location.path("/api/auth");
console.log("error in callback")
$scope.error = true;
}
});
};
})
My rest controller:
#Controller
#RequestMapping("/api")
public class LoginLogoutController {
#RequestMapping(method = RequestMethod.POST, value="/auth")
public void home(#RequestBody String wrap){
System.out.println(wrap);
}
Spring security logs (this logs appear when I try to post login and password):
20:48:06.469 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No HttpSession currently exists
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#11dc2a2b
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/index.html'; against '/logout'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/index.html'; against '/api/auth'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
20:48:06.470 [http-apr-8090-exec-7] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
20:48:06.471 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
20:48:06.471 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
20:48:06.471 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
20:48:06.471 [http-apr-8090-exec-7] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/index.html'; against '/assets/**'
20:48:06.471 [http-apr-8090-exec-7] DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/index.html'; against '/index.html'
20:48:06.471 [http-apr-8090-exec-7] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /index.html; Attributes: [permitAll]
20:48:06.471 [http-apr-8090-exec-7] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#9055e4a6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
20:48:06.474 [http-apr-8090-exec-7] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter#152d862b, returned: 1
20:48:06.474 [http-apr-8090-exec-7] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
20:48:06.474 [http-apr-8090-exec-7] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
20:48:06.474 [http-apr-8090-exec-7] DEBUG o.s.security.web.FilterChainProxy - /index.html reached end of additional filter chain; proceeding with original chain
20:48:06.474 [http-apr-8090-exec-7] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
20:48:06.474 [http-apr-8090-exec-7] DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
20:48:06.474 [http-apr-8090-exec-7] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
Other rest endpoints work fine. Spring default login form works great but issue appears when I try to run with custom login form.

Categories

Resources