Unable to get EnableOauth2Sso Working -- BadCredentialsException: Could not obtain access token

15,977

Solution 1

Creating a Client Application : The context path has to be explicit if you are running both the client and the auth server on localhost, otherwise the cookie paths clash and the two apps cannot agree on a session identifier.

src : https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_authserver

Solution 2

Centinul as you've figured out this happens due to a cookie conflict, unfortunately cookies don't respect the port numbers. And so both Apps interfere with each other since both are setting JSESSIONID.

There are two easy workarounds:

  1. use server.context-path to move each App to different paths, note that you need to do this for both
  2. set the server.session.cookie.name for one App to something different, e.g., APPSESSIONID

I would suggest to put this workaround in a profile that you activate for localhost only.

Share:
15,977
Centinul
Author by

Centinul

Updated on June 07, 2022

Comments

  • Centinul
    Centinul almost 2 years

    I'm trying to get a simple Spring OAuth2 SSO application working and I've been unable to do so. Here's the steps and results of what's happened:

    1. Hit endpoint /user, which is secured by OAuth2
    2. I get forwarded to a simple Spring OAuth2 authorization server
    3. I authenticate to the authorization server
    4. I approved the access
    5. Then I get a white label error page on the OAuth2 SSO application with the following:

      Whitelabel Error Page
      
      This application has no explicit mapping for /error, so you are seeing this as a fallback.
      
      Mon Jul 13 08:19:18 EDT 2015
      There was an unexpected error (type=Unauthorized, status=401).
      Authentication Failed: Could not obtain access token
      

    The authorization code is in the URL. Here is the sample URL below:

    http://localhost:8083/login?code=9s63rU&state=Fo9S2M
    

    I'm not seeing an HTTP POST to the authorization server /oauth/token endpoint to acquire a JWT. I validated this through the /trace endpoint on the authorization server.

    The exception stack is:

    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/css/**'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/js/**'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/images/**'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/**/favicon.ico'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/error'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/health']
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/health'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/health/**']
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/health/**'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/health.*']
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/health.*'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/info']
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/info'
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/info/**']
    2015-07-13 08:23:32.695 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/info/**'
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/info.*']
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/info.*'
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/restart']
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/restart'
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/restart/**']
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/restart/**'
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/restart.*']
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/restart.*'
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env']
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/env'
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env/**']
    2015-07-13 08:23:32.696 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/env/**'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/env.*']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/env.*'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/refresh']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/refresh'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/refresh/**']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/refresh/**'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/refresh.*']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/refresh.*'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/metrics'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics/**']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/metrics/**'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/metrics.*']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/metrics.*'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/pause']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/pause'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/pause/**']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/pause/**'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/pause.*']
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/pause.*'
    2015-07-13 08:23:32.699 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/resume']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/resume'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/resume/**']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/resume/**'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/resume.*']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/resume.*'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/dump'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump/**']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/dump/**'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/dump.*']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/dump.*'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/configprops'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops/**']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/configprops/**'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/configprops.*']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/configprops.*'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/trace'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace/**']
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/trace/**'
    2015-07-13 08:23:32.700 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/trace.*']
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/trace.*'
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans']
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/beans'
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans/**']
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/beans/**'
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/beans.*']
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/beans.*'
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings']
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/mappings'
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings/**']
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/mappings/**'
    2015-07-13 08:23:32.701 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/mappings.*']
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/mappings.*'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig']
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/autoconfig'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig/**']
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/autoconfig/**'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/autoconfig.*']
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/autoconfig.*'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/login' matched by universal pattern '/**'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.security.web.FilterChainProxy        : /login?code=9s63rU&state=Fo9S2M at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.security.web.FilterChainProxy        : /login?code=9s63rU&state=Fo9S2M at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.security.web.FilterChainProxy        : /login?code=9s63rU&state=Fo9S2M at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
    2015-07-13 08:23:32.702 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@59b4132c
    2015-07-13 08:23:32.703 DEBUG 3516 --- [nio-8083-exec-7] o.s.security.web.FilterChainProxy        : /login?code=9s63rU&state=Fo9S2M at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
    2015-07-13 08:23:32.703 DEBUG 3516 --- [nio-8083-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/logout'
    2015-07-13 08:23:32.703 DEBUG 3516 --- [nio-8083-exec-7] o.s.security.web.FilterChainProxy        : /login?code=9s63rU&state=Fo9S2M at position 5 of 11 in additional filter chain; firing Filter: 'OAuth2ClientAuthenticationProcessingFilter'
    2015-07-13 08:23:32.703 DEBUG 3516 --- [nio-8083-exec-7] uth2ClientAuthenticationProcessingFilter : Request is to process authentication
    2015-07-13 08:23:32.704 DEBUG 3516 --- [nio-8083-exec-7] uth2ClientAuthenticationProcessingFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Could not obtain access token
    2015-07-13 08:23:32.705 DEBUG 3516 --- [nio-8083-exec-7] uth2ClientAuthenticationProcessingFilter : Updated SecurityContextHolder to contain null Authentication
    2015-07-13 08:23:32.705 DEBUG 3516 --- [nio-8083-exec-7] uth2ClientAuthenticationProcessingFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@6a650b1c
    2015-07-13 08:23:32.705 DEBUG 3516 --- [nio-8083-exec-7] .a.SimpleUrlAuthenticationFailureHandler : No failure URL set, sending 401 Unauthorized error
    2015-07-13 08:23:32.705 DEBUG 3516 --- [nio-8083-exec-7] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
    2015-07-13 08:23:32.705 DEBUG 3516 --- [nio-8083-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
    

    My sample OAuth2 SSO application:

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.security.oauth2.sso.EnableOAuth2Sso;
    import org.springframework.cloud.security.oauth2.sso.OAuth2SsoConfigurerAdapter;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.security.Principal;
    
    @SpringBootApplication
    public class OAuth2ClientApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OAuth2ClientApplication.class, args);
        }
    
        @RestController
        public static class SecuredController {
            @RequestMapping("/user")
            public Principal user(Principal user) {
                return user;
            }
        }
    
        @Configuration
        @EnableOAuth2Sso
        public static class OAuthSsoConfig extends OAuth2SsoConfigurerAdapter {
            @Override
            public void configure(HttpSecurity http) throws Exception {
                http.logout()
                        .and().antMatcher("/**")
                        .authorizeRequests()
                        .antMatchers("/index.html", "/home.html", "/", "/login").permitAll()
                        .anyRequest()
                        .authenticated()
                        .and().csrf().disable();
            }
        }
    }
    

    The POM:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>test</groupId>
        <artifactId>oauth2-client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>OAuth2 Client</name>
        <description>OAuth2 Client POC</description>
    
        <parent>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>Angel.SR3</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-oauth2</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-jwt</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    

    My application.properties file:

    server.port=8083
    security.basic.enabled=false
    spring.oauth2.client.accessTokenUri=http://localhost:8081/oauth/token
    spring.oauth2.client.userAuthorizationUri=http://localhost:8081/oauth/authorize
    spring.oauth2.client.clientId=oauth2Client
    spring.oauth2.client.clientSecret=oauth2ClientSecret
    
    spring.oauth2.resource.jwt.keyUri=http://localhost:8081/oauth/token_key
    
    logging.level.org.springframework.security=DEBUG
    

    If you need the code for the authorization server please let me know.

    :: UPDATE 1 ::

    I started debugging this and come to find out the actual exception being thrown is an InvalidRequestException with a message of: Possible CSRF detected - state parameter was present but no state could be found on line 244 of AuthorizationCodeAccessTokenProvider.

    I tried modifying my Oauth2SsoConfigurerAdapter to this, but I'm still getting the same exception:

    @Configuration
    protected static class SecurityConfiguration extends OAuth2SsoConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.logout().and().antMatcher("/**").authorizeRequests()
                    .antMatchers("/index.html", "/home.html", "/", "/login").permitAll()
                    .anyRequest().authenticated().and().csrf()
                    .csrfTokenRepository(csrfTokenRepository()).and()
                    .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
        }
    
        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())) {
                            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;
        }
    }
    

    :: UPDATE 2 ::

    The InvalidRequestException is being thrown because the preservedState from the DefaultAccessTokenRequest is returning null (see line 239 of AuthorizationCodeAccessTokenProvider).

    The preservedState is set on the DefaultAccessTokenRequest in the Oauth2RestTemplate on line 212 and I determined that the DefaultOauth2ClientContext map was empty and returning null.

    I'll be attempting to validate the setPreserveState call in the DefaultOAuth2ClientContext next.

    :: UPDATE 3 ::

    I updated my client configuration to use Github instead of my own Spring OAuth2 authorization server and it works. To me that indicates there may be a problem with my authorization server configuration.

    I'll try and do a bit of debugging on my OAuth server to see if I can figure out what's going wrong.

    :: UPDATE 4 ::

    Success! I was running the OAuth2 authorization and client servers on the same host, but different ports. When I set the context path of the client to something other than the root it all started working.

    I suspect this has something to do with JSESSIONID and cookies. Could anyone link me to documentation to explain how this works for future reference?

    Thanks!