Request 'GET /sw.js' doesn't match 'POST /login Spring Security - spring

I am running Spring Boot v2.3.2.RELEASE, Spring v5.2.8.RELEASE and after a successful login I get Request 'GET /sw.js' doesn't match 'POST /login. This happens in Chrome but not in Firefox.
This is my security config class:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);
#Autowired
private LdapAuthenticationProvider authProvider;
/**
* Defines the web based security configuration.
*
* #param http It allows configuring web based security for specific http requests.
* #throws Exception
*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/images/**").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.formLogin()
.loginPage("/login") //custom login page
.permitAll(); // permit everyone the /login page
}
/**
* Sets a custom authentication provider.
*
* #param auth SecurityBuilder used to create an AuthenticationManager.
* #throws Exception
*/
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider);
}
My home controller is:
#RequestMapping("/")
public String index(Principal principal) throws IsimConnectionException {
Authentication authentication = (Authentication) principal;
if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) {
...
My login controller is:
#Controller
public class LoginController {
#GetMapping("/login")
public String login(){
return "login";
}
}
Here is my stack:
2021-09-27 15:10:12,119 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.context.HttpSessionSecurityContextRepository: Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl#ac138ad5: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#ac138ad5: Principal: xxx; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 2B1ED69302276F95FB5CB97E87F7CF64; Not granted any authorities'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.util.matcher.AntPathRequestMatcher: Request 'GET /error' doesn't match 'POST /logout'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 6 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.util.matcher.AntPathRequestMatcher: Request 'GET /error' doesn't match 'POST /login'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.savedrequest.HttpSessionRequestCache: saved request doesn't match
2021-09-27 15:10:12,120 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2021-09-27 15:10:12,121 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2021-09-27 15:10:12,121 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.authentication.AnonymousAuthenticationFilter: SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken#ac138ad5: Principal: asusti; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 2B1ED69302276F95FB5CB97E87F7CF64; Not granted any authorities'
2021-09-27 15:10:12,121 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2021-09-27 15:10:12,121 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2021-09-27 15:10:12,121 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2021-09-27 15:10:12,122 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.FilterChainProxy$VirtualFilterChain: /error reached end of additional filter chain; proceeding with original chain
2021-09-27 15:10:12,123 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.access.ExceptionTranslationFilter: Chain processed normally
2021-09-27 15:10:12,123 DEBUG [http-nio-8080-exec-2] org.springframework.security.web.context.SecurityContextPersistenceFilter: SecurityContextHolder now cleared, as request processing completed
Can you please suggest what is missing in my configuration?
Update:
This is the network screenshot when the error appears from Chrome:
My login.html is:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Login page </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<form name="f" th:action="#{/login}" method="post">
<fieldset>
<legend>Please Login</legend>
<div th:if="${param.error}" class="alert alert-error">
Invalid username and password.
</div>
<div th:if="${param.logout}" class="alert alert-success">
You have been logged out.
</div>
<label for="username">Username</label>
<input type="text" id="username" name="username"/>
<label for="password">Password</label>
<input type="password" id="password" name="password"/>
<div class="form-actions">
<button type="submit" class="btn">Log in</button>
</div>
</fieldset>
</form>
</div>
</body>
</html>
Here is the error sw.js line no 18 that is throwing 404 error. work-box-core.. not found:

Related

CustomAuthenticationProvider doesn't get called spring-security 5.2

I have converted an app to use spring and spring security I am using version 5.2. When I try and login my CustomAuthProvider doesn't get called. It does hit the security endpoint 'login' in the jsp and has an anonymous role. Below are the relevant configs.
#ComponentScan(basePackages = {"com.example"})
#Import({com.example.Configuration.class, WebSecurityConfig.class})
public class AppConfig {
servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/mvc/*");
Register the DelegatingFilterProxy
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
The WebSecurity class
#Configuration
#EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider)
.userDetailsService(new UserDetails());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and().
authorizeRequests(a ->
a.antMatchers(
"/resources/js/**",
"/resources/scripts/**",
"/login",
"/resources/styles/**",
"/resources/images/**",
"/resources/loginPage.jsp",
"/resources/forgotUserName.jsp",
"/resources/forgotPassword.jsp",
"/mvc/jsonInitialResponse/**")
.permitAll()
.antMatchers(
"/resources/resetPassword.jsp",
"/mvc/jsonResponse/**",
"/mvc/download/**",
"/resources/**"
).authenticated())
.formLogin()
.loginPage("/resources/loginPage.jsp")
.successHandler(new CustomeAuthenticationSuccessHandler())
.failureUrl("/resources/loginPage.jsp?error=true")
.and().anonymous()
.and()
.logout()
.logoutSuccessUrl("/resources/loginPage.jsp")
.permitAll()
.and()
.csrf().disable().cors().disable();
}
}
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Override
public Authentication authenticate(final Authentication authentication) {......}
#Override
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
Any thoughts on what I may be missing? The CustomAuthenticationProvider isn't being called and either is the supports() method.
2020-10-06 12:26:29 DEBUG DefaultSavedRequest:359 - pathInfo: both null (property equals)
2020-10-06 12:26:29 DEBUG DefaultSavedRequest:359 - queryString: both null (property equals)
2020-10-06 12:26:29 DEBUG DefaultSavedRequest:383 - requestURI: arg1=/reinsurance-service-ui-war/resources/login; arg2=/reinsurance-service-ui-war/resources/images/icn-lock.png (property not equals)
2020-10-06 12:26:29 DEBUG HttpSessionRequestCache:95 - saved request doesn't match
2020-10-06 12:26:29 DEBUG FilterChainProxy:328 - /resources/images/icn-lock.png at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-10-06 12:26:29 DEBUG FilterChainProxy:328 - /resources/images/icn-lock.png at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-10-06 12:26:29 DEBUG AnonymousAuthenticationFilter:100 - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#418e8a7d: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffbcba8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 4503EBEA550D56CD4AF5506BC88E7576; Granted Authorities: ROLE_ANONYMOUS'
2020-10-06 12:26:29 DEBUG FilterChainProxy:328 - /resources/images/icn-lock.png at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-10-06 12:26:29 DEBUG FilterChainProxy:328 - /resources/images/icn-lock.png at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-10-06 12:26:29 DEBUG FilterChainProxy:328 - /resources/images/icn-lock.png at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-10-06 12:26:29 DEBUG AntPathRequestMatcher:177 - Checking match of request : '/resources/images/icn-lock.png'; against '/resources/js/**'
2020-10-06 12:26:29 DEBUG AntPathRequestMatcher:177 - Checking match of request : '/resources/images/icn-lock.png'; against '/resources/scripts/**'
2020-10-06 12:26:29 DEBUG AntPathRequestMatcher:177 - Checking match of request : '/resources/images/icn-lock.png'; against '/resources/styles/**'
2020-10-06 12:26:29 DEBUG AntPathRequestMatcher:177 - Checking match of request : '/resources/images/icn-lock.png'; against '/resources/images/**'
2020-10-06 12:26:29 DEBUG FilterSecurityInterceptor:219 - Secure object: FilterInvocation: URL: /resources/images/icn-lock.png; Attributes: [anonymous]
2020-10-06 12:26:29 DEBUG FilterChainProxy:313 - /resources/images/icn-pencil.png reached end of additional filter chain; proceeding with original chain
2020-10-06 12:26:29 DEBUG FilterSecurityInterceptor:348 - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#418e8a7d: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#fffbcba8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 4503EBEA550D56CD4AF5506BC88E7576; Granted Authorities: ROLE_ANONYMOUS
2020-10-06 12:26:29 DEBUG HstsHeaderWriter:169 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#51ca55f0
2020-10-06 12:26:29 DEBUG HttpSessionSecurityContextRepository:351 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-10-06 12:26:29 DEBUG ExceptionTranslationFilter:120 - Chain processed normally
2020-10-06 12:26:29 DEBUG SecurityContextPersistenceFilter:119 - SecurityContextHolder now cleared, as request processing completed
2020-10-06 12:26:29 DEBUG AffirmativeBased:66 - Voter: org.springframework.security.web.access.expression.WebExpressionVoter#3fe8aa9d, returned: 1
2020-10-06 12:26:29 DEBUG FilterSecurityInterceptor:243 - Authorization successful
2020-10-06 12:26:29 DEBUG FilterSecurityInterceptor:256 - RunAsManager did not change Authentication object
2020-10-06 12:26:29 DEBUG FilterChainProxy:313 - /resources/images/icn-lock.png reached end of additional filter chain; proceeding with original chain
2020-10-06 12:26:29 DEBUG HstsHeaderWriter:169 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#51ca55f0
2020-10-06 12:26:29 DEBUG HttpSessionSecurityContextRepository:351 - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-10-06 12:26:29 DEBUG ExceptionTranslationFilter:120 - Chain processed normally
2020-10-06 12:26:29 DEBUG SecurityContextPersistenceFilter:119 - SecurityContextHolder now cleared, as request processing completed```

Spring Security Authorization Code not able to fetch token after getting user consent

I have tried to replicate https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_manual but for only GitHub.
The issue is that I get redirected to GitHub, gets authenticated but then nothing happens, it does not actually retrieve the token with the response code etc.
I have searched on numerous threads.
I have the same issue as: Unable to expose endpoint in Spring Boot to receive authorization code from Google
I could try https://dzone.com/articles/spring-boot-oauth2-getting-the-authorization-code but would like Spring to handle as much security stuff as possible not manually make the rest call.
This goes into some detail about modifying filter chain: Spring oauth2 dont redirect to original url
Spring provides OAuth2LoginAuthenticationFilter and OAuth2AuthorizationRequestRedirectFilter but do I have to use implement that?
2019-08-01 04:36:09.473 DEBUG 13884 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/login/github' matched by universal pattern '/**'
2019-08-01 04:36:09.474 DEBUG 13884 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login/github at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-08-01 04:36:09.476 DEBUG 13884 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login/github at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-08-01 04:36:09.477 DEBUG 13884 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2019-08-01 04:36:09.477 DEBUG 13884 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2019-08-01 04:36:09.479 DEBUG 13884 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login/github at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-08-01 04:36:09.480 DEBUG 13884 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login/github at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2019-08-01 04:36:09.488 DEBUG 13884 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login/github at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2019-08-01 04:36:09.489 DEBUG 13884 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login/github' doesn't match 'POST /logout
2019-08-01 04:36:09.490 DEBUG 13884 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy : /login/github at position 6 of 12 in additional filter chain; firing Filter: 'OAuth2ClientAuthenticationProcessingFilter'
2019-08-01 04:36:09.491 DEBUG 13884 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/github'; against '/login/github'
2019-08-01 04:36:09.491 DEBUG 13884 --- [nio-8080-exec-9] uth2ClientAuthenticationProcessingFilter : Request is to process authentication
2019-08-01 04:36:14.533 DEBUG 13884 --- [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#422e37e6
2019-08-01 04:36:14.534 DEBUG 13884 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2019-08-01 04:36:14.534 DEBUG 13884 --- [nio-8080-exec-9] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2019-08-01 04:36:15.238 DEBUG 13884 --- [nio-8080-exec-9] o.s.s.web.DefaultRedirectStrategy : Redirecting to 'https://github.com/login/oauth/authorize?client_id=SOMETHING&redirect_uri=http://localhost:8080/login/oauth2/code/github&response_type=code&state=bT8lSK'
2019-08-01 04:36:15.542 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/login/oauth2/code/github' matched by universal pattern '/**'
2019-08-01 04:36:15.542 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-08-01 04:36:15.542 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-08-01 04:36:15.542 DEBUG 13884 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2019-08-01 04:36:15.543 DEBUG 13884 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#250f33e4. A new one will be created.
2019-08-01 04:36:15.543 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-08-01 04:36:15.543 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2019-08-01 04:36:15.545 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2019-08-01 04:36:15.546 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login/oauth2/code/github' doesn't match 'POST /logout
2019-08-01 04:36:15.546 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 6 of 12 in additional filter chain; firing Filter: 'OAuth2ClientAuthenticationProcessingFilter'
2019-08-01 04:36:15.546 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/oauth2/code/github'; against '/login/github'
2019-08-01 04:36:15.546 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2019-08-01 04:36:15.547 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2019-08-01 04:36:15.550 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2019-08-01 04:36:15.554 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#bc4979c4: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 9ABF40E66AE6EDF4FA955A1EC1E728AA; Granted Authorities: ROLE_ANONYMOUS'
2019-08-01 04:36:15.555 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2019-08-01 04:36:15.555 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2019-08-01 04:36:15.555 DEBUG 13884 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy : /login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2019-08-01 04:36:15.557 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /login/oauth2/code/github' doesn't match 'POST /logout
2019-08-01 04:36:15.557 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/oauth2/code/github'; against '/'
2019-08-01 04:36:15.557 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login/oauth2/code/github'; against '/login**'
2019-08-01 04:36:15.558 DEBUG 13884 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathR
I tried to replicate the tutorial exactly and did some digging around but have not been able to solve the problem.
#EnableOAuth2Client
public class SocialApplication extends WebSecurityConfigurerAdapter {
#Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<OAuth2ClientContextFilter>();
registration.setFilter(filter);
registration.setOrder(-100);
return registration;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**", "/webjars/**", "/error**").permitAll().anyRequest()
.authenticated().and().exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/")).and().logout()
.logoutSuccessUrl("/").permitAll().and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
// #formatter:on
}
private Filter ssoFilter() {
OAuth2ClientAuthenticationProcessingFilter facebookFilter = new OAuth2ClientAuthenticationProcessingFilter(
"/login/github");
OAuth2RestTemplate facebookTemplate = new OAuth2RestTemplate(facebook(), oauth2ClientContext);
facebookFilter.setRestTemplate(facebookTemplate);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(facebookResource().getUserInfoUri(),
facebook().getClientId());
facebook().setUseCurrentUri(false);
facebook().setPreEstablishedRedirectUri("http://localhost:8080/login/oauth2/code/github");
tokenServices.setRestTemplate(facebookTemplate);
facebookFilter.setTokenServices(tokenServices);
return facebookFilter;
}
The problem is
org.springframework.security.access.AccessDeniedException: Access is denied
Based on debug logs it seems that OAuth2LoginAuthenticationFilter is missing in security filter chain, client receives code from gihub authorization server which should be exchanged for token.
This is the request received by client app from authorization server:
/login/oauth2/code/github?code=d899209d67e0105486d8&state=bT8lSK
Which should be intercepted by OAuth2LoginAuthenticationFilter with default filter processing uri: "/login/oauth2/code/*"- this is what you are missing.
Your question:
Spring provides OAuth2LoginAuthenticationFilter and OAuth2AuthorizationRequestRedirectFilter but do I have to use implement that?
Spring security filter chain is not configured to include above mentioned filters by default, so we can provide HttpSecurity.oauth2Login(). For Example:
#Override
public void configure(HttpSecurity http) throws Exception {
http.
.
.oauth2Login()
.
.
.clientRegistrationRepository(clientRegistrationRepository())
.authorizedClientService(oAuth2AuthorizedClientService());
}
#Bean
public ClientRegistrationRepository clientRegistrationRepository() {
ClientRegistration github =
CommonOAuth2Provider.GITHUB.getBuilder("github")
.clientId("ClientId")
.clientSecret("ClientSecret")
.redirectUriTemplate("http://localhost:PORT/contextpath/login/oauth2/code/")
.scope("email","profile")
.build();
//inmemory is temporary
List<ClientRegistration> clientRegistrationList = new ArrayList<>();
clientRegistrationList.add(github);
return new InMemoryClientRegistrationRepository(clientRegistrationList);
}
#Bean
public OAuth2AuthorizedClientService oAuth2AuthorizedClientService() {
return new
InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository());
}
which will configure OAuth2LoginAuthenticationFilter and OAuth2AuthorizationRequestRedirectFilter for more information see https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/html/oauth2login-advanced.html
Alternative to http.oauth2Login() for adding those 2 filters is to manually configure and add them, which is a little bit not elegant. For example:
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(oAuth2LoginAuthenticationProvider());
}
#Bean
public DefaultAuthorizationCodeTokenResponseClient defaultAuthorizationCodeTokenResponseClient(){
return new DefaultAuthorizationCodeTokenResponseClient();
}
#Bean
public DefaultOAuth2UserService defaultOAuth2UserService(){
return new DefaultOAuth2UserService();
}
#Bean
public OAuth2LoginAuthenticationProvider oAuth2LoginAuthenticationProvider(){
return new OAuth2LoginAuthenticationProvider(defaultAuthorizationCodeTokenResponseClient(),defaultOAuth2UserService());
}
#Bean
public OAuth2LoginAuthenticationFilter oAuth2LoginAuthenticationFilter() throws Exception {
OAuth2LoginAuthenticationFilter oAuth2LoginAuthenticationFilter =
new OAuth2LoginAuthenticationFilter(clientRegistrationRepository(),oAuth2AuthorizedClientService());
oAuth2LoginAuthenticationFilter.setAuthenticationManager(super.authenticationManagerBean());
return oAuth2LoginAuthenticationFilter;
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.
.
.addFilterBefore(oAuth2LoginAuthenticationFilter(), RequestCacheAwareFilter.class)
.addFilterBefore(oAuth2AuthorizationRequestRedirectFilter(),OAuth2LoginAuthenticationFilter.class)
.
.
}

Getting 404 after oauth2 authentication success and an anonymous token

I am using oauth2 with springboot 1.5.6.RELEASE and I am using jdbc authentication with oauth2.
I added the property: security.oauth2.resource.filter-order = 3
1- AuthorizationServerConfigurerAdapter:
#Configuration
#EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
#Autowired
#Qualifier("authenticationManagerBean")
#Lazy
private AuthenticationManager authenticationManager;
#Autowired
private Environment env;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);
endpoints.authenticationManager(authenticationManager);
}
#Bean
public TokenStore tokenStore() {
return new JdbcTokenStore(dataSource());
}
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource());
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
}
2- ResourceServerConfigurerAdapter
#EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/ws/**").authorizeRequests().anyRequest().authenticated();
}
}
3- SecurityConfig
#Configuration
#EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private CustomAuthenticationSuccessHandler successHandler;
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/", "/registerCompany", "/registerEmployee", "/jobs", "/returnPassword", "/resetPassword",
"/faces/public/**", "/resources/**", "/template/**", "/faces/fonts/*",
"/faces/javax.faces.resource/**", "/ws/**", "/login", "/oauth/**", "/error")
.permitAll().antMatchers("/admin/**", "/faces/admin/**").hasAuthority("ROLE_ADMIN")
.antMatchers("/employeeProfile", "/employeeMainPage", "/employeeAskJob").hasAuthority("ROLE_EMPLOYEE")
.antMatchers("/companyProfile", "/companyMainPage", "/companyPostJob", "/companySearch",
"/branchProfile")
.hasAnyAuthority("ROLE_COMPANY,ROLE_BRANCH,ROLE_ADMIN").anyRequest().fullyAuthenticated().and()
.formLogin().loginPage("/login").permitAll().successHandler(successHandler).failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password").and().logout().deleteCookies("JSESSIONID")
.logoutUrl("/logout").deleteCookies("remember-me").logoutSuccessUrl("/").permitAll().and().rememberMe();
// http.sessionManagement().invalidSessionUrl("/login?invalidSession");
// cache resources
http.headers().addHeaderWriter(new DelegatingRequestMatcherHeaderWriter(
new AntPathRequestMatcher("/javax.faces.resource/**"), new HeaderWriter() {
#Override
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
response.addHeader("Cache-Control", "private, max-age=86400");
}
})).defaultsDisabled();
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(11);
}
}
I am trying to generate a token using postman with a post request to url http://localhost:8082/dawam2/oauth/token?grant_type=password
and I use basic authentication and set the username=myclient_id and password=myclient_secret. So the header (Authorization : Basic Basic bXljbGllbnRfaWQ6bXljbGllbnRfc2VjcmV0) was generated
and I set the header Content-Type: application/x-www-form-urlencoded; charset=utf-8.
The response I am getting instead of a generated token :
!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Not Found</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.0.M18</h3></body></html>
Here are the debugging info:
2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/oauth/token']
2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - matched
2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-09-26 15:32:16,833 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#1d47c7a
2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', GET]
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/logout'
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', POST]
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /oauth/token' doesn't match 'POST /logout
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', PUT]
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /oauth/token' doesn't match 'PUT /logout
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', DELETE]
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /oauth/token' doesn't match 'DELETE /logout
2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - No matches found
2017-09-26 15:32:16,834 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 5 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-09-26 15:32:16,834 DEBUG o.s.s.w.a.w.BasicAuthenticationFilter - Basic Authentication Authorization header found for user 'myclient_id'
2017-09-26 15:32:16,834 DEBUG o.s.s.a.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-09-26 15:32:16,849 DEBUG o.s.s.w.a.w.BasicAuthenticationFilter - Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#d9cf8114: Principal: org.springframework.security.core.userdetails.User#6a9879e3: Username: myclient_id; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; 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_EMPLOYEE
2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken#d9cf8114: Principal: org.springframework.security.core.userdetails.User#6a9879e3: Username: myclient_id; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; 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_EMPLOYEE'
2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.s.CompositeSessionAuthenticationStrategy - Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy#15d6aaa
2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-09-26 15:32:16,850 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password; Attributes: [fullyAuthenticated]
2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#d9cf8114: Principal: org.springframework.security.core.userdetails.User#6a9879e3: Username: myclient_id; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; 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_EMPLOYEE
2017-09-26 15:32:16,851 DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter#14cb584, returned: 1
2017-09-26 15:32:16,851 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
2017-09-26 15:32:16,851 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
2017-09-26 15:32:16,851 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password reached end of additional filter chain; proceeding with original chain
2017-09-26 15:32:16,853 DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
2017-09-26 15:32:16,853 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/oauth/token']
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/error'; against '/oauth/token'
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/oauth/token_key']
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/error'; against '/oauth/token_key'
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/oauth/check_token']
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/error'; against '/oauth/check_token'
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - No matches found
2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-09-26 15:32:16,854 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No HttpSession currently exists
2017-09-26 15:32:16,854 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', GET]
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/error'; against '/logout'
2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', POST]
2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /error' doesn't match 'POST /logout
2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', PUT]
2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /error' doesn't match 'PUT /logout
2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern='/logout', DELETE]
2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /error' doesn't match 'DELETE /logout
2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - No matches found
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request 'GET /error' doesn't match 'POST /login
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 6 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 7 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 8 of 12 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-09-26 15:32:16,855 DEBUG 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-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password reached end of additional filter chain; proceeding with original chain
2017-09-26 15:32:16,856 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2017-09-26 15:32:16,856 DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
2017-09-26 15:32:16,856 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
How can I fix this issue?
The issue was related to Jersey configuration, it was stealing requests from oauth2, i had to reconfigure it with #ApplicationPath("/ws")
so the configuration now looks like :
#Configuration
#ApplicationPath("/ws")
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(DawamService.class);
}
}
and my webservice implementation class like :
#Component
#Path("/dawam")
public class DawamService extends DawamServiceBase {
#GET
#Produces({ MediaType.TEXT_HTML })
#Path("/test")
public String getHTML() {
System.out.println("##### Welcome to test webservice #########");
return "Welcome to test webservice";
}
}
I have the same problem and I can fixed it.
In my case the reason was in the following:
My servlet-mapping for dispather servlet in web.xml
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
It means the all http requests for access to your resources should be started with '/api' (ex. /api/user/2 or /api/login) even if #RequestMapping points as '/user/{id}' or /login. When you request a token by oauth2/token URL, spring or other filters handle it, but dispatcherServlet could not find any controller corresponding to your request and we have 404 error.
To resolve this, I just added the one method to endpoints in AuthorizationServerConfiguration class.
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter
...
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore)
.prefix("/api") //<---- PREFIX WAS ADDED
.userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
...
}
I think the
.pathMapping("/oauth/token", "/api/oauth/token")
code instead of .prefix("/api") also can resolve the problem.
It changes request for getting the tokens.
After made change I get the tokens by URL
/api/oauth/token
Of course I can mistake but it works for me. Thanks.

Oauth 2.0 configuration conflicts with Spring Security

I am trying to configure an Oauth2 with Spring Security. But my Oauth configuration conflicts with Spring Security configuration.
It seems like the Resource Server configuration is not limited to /api/v0/.* but is overriding ALL security configuration. Resource Server works well. But my form-based authentication with Spring Security doesn't work - it returns the HTTP 404 error.
I have the following code in my WebSecurityConfigurerAdapter
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ADMINISTRATOR')")
.antMatchers("/1/admin/**").access("hasRole('ADMINISTRATOR')")
.antMatchers("/profile**").authenticated()
.antMatchers("/oauth/authorize").authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=1")
.loginProcessingUrl("/login-attempt")
.defaultSuccessUrl("/", false)
.and()
.csrf();
}
This is my configuration from ResourceServerConfigurerAdapter
#Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.regexMatchers("/api/v0/.*").authenticated();
}
Logs
AntPathRequestMatcher:151 - Checking match of request : '/login-attempt'; against '/html/**'
AntPathRequestMatcher:151 - Checking match of request : '/login-attempt'; against '/webapi/**'
OrRequestMatcher:65 - Trying to match using Ant [pattern='/oauth/token']
AntPathRequestMatcher:151 - Checking match of request : '/login-attempt'; against '/oauth/token'
OrRequestMatcher:65 - Trying to match using Ant [pattern='/oauth/token_key']
AntPathRequestMatcher:151 - Checking match of request : '/login-attempt'; against '/oauth/token_key'
OrRequestMatcher:65 - Trying to match using Ant [pattern='/oauth/check_token']
AntPathRequestMatcher:151 - Checking match of request : '/login-attempt'; against '/oauth/check_token'
OrRequestMatcher:72 - No matches found
FilterChainProxy:324 - /login-attempt at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
FilterChainProxy:324 - /login-attempt at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
FilterChainProxy:324 - /login-attempt at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
HstsHeaderWriter:128 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#2fa4c8cd
FilterChainProxy:324 - /login-attempt at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
AntPathRequestMatcher:151 - Checking match of request : '/login-attempt'; against '/logout'
FilterChainProxy:324 - /login-attempt at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
BearerTokenExtractor:54 - Token not found in headers. Trying request parameters.
BearerTokenExtractor:57 - Token not found in request parameters. Not an OAuth2 request.
OAuth2AuthenticationProcessingFilter:141 - No token in request, will continue chain.
FilterChainProxy:324 - /login-attempt at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
FilterChainProxy:324 - /login-attempt at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
FilterChainProxy:324 - /login-attempt at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
AnonymousAuthenticationFilter:100 - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#9056f12c: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#380f4: RemoteIpAddress: 127.0.0.1;SessionId:672t27n01ruouli4a041a0xq;Granted Authorities: ROLE_ANONYMOUS'
FilterChainProxy:324 - /login-attempt at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
FilterChainProxy:324 - /login-attempt at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
FilterChainProxy:324 - /login-attempt at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
RegexRequestMatcher:106 - Checking match of request : '/login-attempt'; against '/api/v0/.*'
FilterSecurityInterceptor:209 - Public object - authentication not attempted
FilterChainProxy:309 - /login-attempt reached end of additional filter chain; proceeding with original chain
What am I doing wrong? Thanks in advance!
Not sure whether it fixes your problem or not. Lets give a try.
Add
#Order(1)
#Order(2)
to your configuration classes and try again.

Spring OAuth: Custom form for authenticating authorization endpoint

How can I set up a custom login form to protect my /oauth/authorize endpoint in an Spring Boot Application that is both a Authorization and Resource Server? I want to achieve that a user has to log in to make requests to /oauth/authorize. All resources, that are not /login and /oauth/** should be handled as secured resources protected by OAuth (requiring a valid access token)
So when a user calls localhost:1234/oauth/authorize?client_id=client&response_type=token&redirect_uri=http://localhost:5678 he is first redirected to the login form and after successfully loggin in redirect to the /oauth/authorize endpoint where the implicit OAuth flow proceeds.
When I try the following it works, using the standard basic authentication popup window
#Configuration
#EnableAuthorizationServer
public class OAuthConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
#Override
public void configure(final ClientDetailsServiceConfigurer clients)
throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("implicit", "refresh_token")
.scopes("read");
}
}
The Resource config
#Configuration
#EnableResourceServer
public class ResourceConfiguration
extends ResourceServerConfigurerAdapter
{
#Override
public void configure(final HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests().antMatchers("/login").permitAll().and()
.authorizeRequests().anyRequest().authenticated();
// #formatter:on
}
}
The Web Security config
#Configuration
public class WebSecurityConfiguration
extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/oauth/authorize").authenticated().and()
.authorizeRequests().anyRequest().permitAll().and().httpBasic();
}
}
but as soon as I replace httpBasic() with the following it fails:
#Configuration
public class WebSecurityConfiguration
extends WebSecurityConfigurerAdapter
{
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/oauth/authorize").authenticated().and()
.authorizeRequests().anyRequest().permitAll().and().formLogin().loginPage("/login").and().csrf()
.disable();
}
}
and my POST from the login Page is not redirected, it always just returns to /login
The output from the console is as following
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/css/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/js/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/images/**'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/**/favicon.ico'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/error'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/token']
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/oauth/token'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/token_key']
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/oauth/token_key'
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/oauth/check_token']
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/oauth/check_token'
o.s.s.web.util.matcher.OrRequestMatcher : No matches found
o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration$NotOAuthRequestMatcher#5fe3eb5f
o.s.s.web.util.matcher.OrRequestMatcher : matched
o.s.security.web.FilterChainProxy : /login at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
o.s.security.web.FilterChainProxy : /login at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
o.s.security.web.FilterChainProxy : /login at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#51c78264
o.s.security.web.FilterChainProxy : /login at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/logout'
o.s.security.web.FilterChainProxy : /login at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2AuthenticationProcessingFilter'
o.s.s.o.p.a.BearerTokenExtractor : Token not found in headers. Trying request parameters.
o.s.s.o.p.a.BearerTokenExtractor : Token not found in request parameters. Not an OAuth2 request.
p.a.OAuth2AuthenticationProcessingFilter : No token in request, will continue chain.
o.s.security.web.FilterChainProxy : /login at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
o.s.security.web.FilterChainProxy : /login at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
o.s.security.web.FilterChainProxy : /login at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: BDCE2D7EA7252AEA2506633726B8BA19; Granted Authorities: ROLE_ANONYMOUS'
o.s.security.web.FilterChainProxy : /login at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
o.s.security.web.FilterChainProxy : /login at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
o.s.security.web.FilterChainProxy : /login at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/login'; against '/login'
o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /login; Attributes: [#oauth2.throwOnError(permitAll)]
o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#90541710: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#166c8: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: BDCE2D7EA7252AEA2506633726B8BA19; Granted Authorities: ROLE_ANONYMOUS
o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#bba9bfc, returned: 1
o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
o.s.security.web.FilterChainProxy : /login reached end of additional filter chain; proceeding with original chain
o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Adding an #Order(-10) to the WebSecurityConfig resolves the issue. I think this annoation ensures that the WebSecurityConfig is used before the ResourceConfig. My final configuration looks like this:
#Configuration
#Order(-10)
public class WebSecurityConfig
extends WebSecurityConfigurerAdapter
{
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http.authorizeRequests().antMatchers("/oauth/authorize").authenticated()
.and()
.authorizeRequests().anyRequest().permitAll()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.csrf().disable();
// #formatter:on
}
}

Resources