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

Centinul picture Centinul · Jul 13, 2015 · Viewed 15k times · Source

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!

Answer

acpuma picture acpuma · Dec 24, 2016

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