3. Resource Server

To use the access token you need a Resource Server (which can be the same as the Authorization Server). Creating a Resource Server is easy, just add @EnableResourceServer and provide some configuration to allow the server to decode access tokens. If your application is also an Authorization Server it already knows how to decode tokens, so there is nothing else to do. If your app is a standalone service then you need to give it some more configuration, one of the following options:

If you specify both the user-info-uri and the token-info-uri then you can set a flag to say that one is preferred over the other (prefer-token-info=true is the default).

Alternatively (instead of user-info-uri or token-info-uri) if the tokens are JWTs you can configure a security.oauth2.resource.jwt.key-value to decode them locally (where the key is a verification key). The verification key value is either a symmetric secret or PEM-encoded RSA public key. If you don’t have the key and it’s public you can provide a URI where it can be downloaded (as a JSON object with a “value” field) with security.oauth2.resource.jwt.key-uri. E.g. on PWS:

$ curl https://uaa.run.pivotal.io/token_key
{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}

Additionally, if your authorization server has an endpoint that returns a set of JSON Web Keys(JWKs), you can configure security.oauth2.resource.jwk.key-set-uri. E.g. on PWS:

$ curl https://uaa.run.pivotal.io/token_keys
{"keys":[{"kid":"key-1","alg":"RS256","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"]}
[Note]Note

Configuring both JWT and JWK properties will cause an error. Only one of security.oauth2.resource.jwt.key-uri (or security.oauth2.resource.jwt.key-value) and security.oauth2.resource.jwk.key-set-uri should be configured.

[Warning]Warning

If you use the security.oauth2.resource.jwt.key-uri or security.oauth2.resource.jwk.key-set-uri, the authorization server needs to be running when your application starts up. It will log a warning if it can’t find the key, and tell you what to do to fix it.

OAuth2 resources are protected by a filter chain with order security.oauth2.resource.filter-order.

By default the filters in AuthorizationServerConfigurerAdapter come first, followed by those in ResourceServerConfigurerAdapter, followed by those in WebSecurityConfigurerAdapter.

This means that all application endpoints will require bearer token authentication unless one of two things happens:

  1. The filter chain order is changed or
  2. The ResourceServerConfigurerAdapter set of authorized requests is narrowed

The first, changing the filter chain order, can be done by moving WebSecurityConfigurerAdapter in front of ResourceServerConfigurerAdapter like so:

@Order(2)
@EnableWebSecurity
public WebSecurityConfig extends WebSecurityConfigurerAdapter {
        // ...
}
[Note]Note

Resource Server’s default @Order value is 3 which is why the example sets Web’s @Order to 2, so that it’s evaluated earlier.

While this may work, it’s a little odd since we may simply trade one problem:

ResourceServerConfigurerAdapter is handling requests it shouldn’t

For another:

WebSecurityConfigurerAdapter is handling requests it shouldn’t

The more robust solution, then, is to indicate to ResourceServerConfigurerAdapter which endpoints should be secured by bearer token authentication.

For example, the following configures Resource Server to secure the web application endpoints that begin with /rest:

@EnableResourceServer
public ResourceServerConfig extends ResourceServerConfigurerAdapter {
        @Override
    protected void configure(HttpSecurity http) {
        http
            .requestMatchers()
                .antMatchers("/rest/**")
            .authorizeRequests()
                .anyRequest().authenticated();
    }
}