Skip to content
This repository

OAuth 2 Developers Guide

Introduction

This is the user guide for the support for OAuth 2.0. For OAuth 1.0, everything is different, so see its user guide. This OAuth 2 module supports the latest version of OAuth 2 draft (which is draft 31).

This user guide is divided into two parts, the first for the OAuth 2.0 provider, the second for the OAuth 2.0 client.

OAuth 2.0 Provider

The OAuth 2.0 provider mechanism is responsible for exposing OAuth 2.0 protected resources. The configuration involves establishing the OAuth 2.0 clients that can access its protected resources on behalf of a user. The provider does this by managing and verifying the OAuth 2.0 tokens that can be used to access the protected resources. Where applicable, the provider must also supply an interface for the user to confirm that a client can be granted access to the protected resources (i.e., a confirmation page).

Managing Clients

The entry point into your database of clients is defined by the ClientDetailsService. You must define your own ClientDetailsService that will load ClientDetails by the clientId. Note the existence of an in-memory implementation of ClientDetailsService.

When implementing your ClientDetailsService consider returning instances of (or extending) BaseClientDetails.

Managing Tokens

The AuthorizationServerTokenServices interface defines the operations that are necessary to manage OAuth 2.0 tokens. Note the following:

  • When an access token is created, the authentication must be stored so that handlers of the access token can reference it.
  • The access token is used to load the authentication that was used to authorize its creation.

When creating your AuthorizationServerTokenServices implementation, you may want to consider using the DefaultTokenServices which creates tokens via random value and handles everything except for the persistence of the tokens which it delegates to a TokenStore. There is an in-memory implementation of the TokenStore that may be suitable.

There is also a jdbc implementation available that stores tokens and their Authentication in BLOB columns in a provided DataSource. To use that, you have to add a table to your data-source:

CREATE TABLE oauth_refresh_token ( TOKEN_ID VARCHAR(64) NOT NULL PRIMARY KEY, TOKEN BLOB NOT NULL, authentication BLOB NOT NULL);

Depending on your application configuration, access to this DataSource may not be synchronized and race conditions can occur. Please have a look at Spring's Transaction Support to see whether this applies to your use case. In particular you might find it essential to wrap all methods of the AuthorizationServerTokenServices in a transaction with a high isolation in the case that you expect multiple concurrent access token requests for the same client and user, e.g.

<tx:advice id="tokenAdvice">
  <tx:attributes>
    <tx:method name="*" isolation="REPEATABLE_READ" />
  </tx:attributes>
</tx:advice>

<aop:config>
  <aop:pointcut id="tokenServicesExecutions" expression="execution(* org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices.*(..))" />
  <aop:advisor advice-ref="tokenAdvice" pointcut-ref="tokenServicesExecutions"/>
</aop:config>

OAuth 2.0 Provider Implementation

The provider role in OAuth 2.0 is actually split between Authorization Service and Resource Service, and while these sometimes reside in the same application, with Spring Security OAuth you have the option to split them across two applications, and also to have multiple Resource Services that share an Authorization Service. The requests for the tokens are handled by Spring MVC controller endpoints, and access to protected resources is handled by standard Spring Security request filters. The following endpoints are required in the Spring Security filter chain in order to implement OAuth 2.0 Authorization Server:

  • AuthorizationEndpoint is used to service requests for authorization. Default URL: /oauth/authorize.
  • TokenEndpoint is used to service requests for access tokens. Default URL: /oauth/token.

The following filter is required to implement an OAuth 2.0 Resource Server:

For all the OAuth 2.0 provider features, configuration is simplified using the custom spring configuration elements. The schema for these elements rests at http://www.springframework.org/schema/security/spring-security-oauth2.xsd. The namespace is http://www.springframework.org/schema/security/oauth2. Further details of the features in the namespace are given below.

Authorization Server Configuration

As you configure the Authorization Server, you have to consider the grant type that the client is to use to obtain an access token from the end-user (e.g. authorization code, user credentials, refresh token). The configuration of the server is used to provide implementations of the client details service and token services and to enable or disable certain aspects of the mechanism globally. Note, however, that each client can be configured specifically with permissions to be able to use certain authorization mechanisms and access grants. I.e. just because your provider is configured to support the "client credentials" grant type, doesn't mean that a specific client is authorized to use that grant type.

The <authorization-server/> element is used to configure the OAuth 2.0 Authorization Server mechanism. The following attributes can be applied to the authorization-server element:

  • client-details-service-ref: A reference to the bean that defines the client details service.
  • token-services-ref: A reference to the bean that defines the token services.
  • user-approval-handler-ref: A reference to the bean that defines the user approval handler.
  • user-approval-page: The URL of the page that handles the user approval form.
  • approval-parameter-name: The name of the form parameter that is used to indicate user approval of the client authentication request.

An important aspect of the provider configuration is the way that a authorization code is supplied to an OAuth client. A authorization code is obtained by the OAuth client by directing the end-user to an authorization page where the user can enter her credentials, resulting in a redirection from the provider authorization server back to the OAuth client with the authorization code. Examples of this are elaborated in the OAuth 2 specification.

Grant Types

The authorization code grant type is configured via the authorization-code child element of the authorization-server element. The authorization-code element supports the following attributes:

  • disabled: Boolean value specifying whether the authorization code mechanism is disabled. This effectively disables the authorization code grant mechanism.
  • authorization-code-services-ref: The reference to the bean that defines the authorization code services (instance of org.springframework.security.oauth2.provider.code.AuthorizationCodeServices). Default is InMemoryAuthorizationCodeServices.

Other grant types are also included as child elements of the authorization-server.

Configuring Client Details

The client-details-service element is used to define an in-memory implementation of the client details service. It takes an id attribute and an arbitrary number of client child elements that define the following attributes for each client:

  • client-id: (required) The client id.
  • secret: The client secret, if any. Not required for the implicit flow.
  • scope: The scope to which the client is limited (comma-separated). If scope is undefined or empty (the default) the client is not limited by scope.
  • authorized-grant-types: Flows that are authorized for the client to use (comma-separated). Default value is "authorization_code,refresh_token".
  • authorities: Authorities that are granted to the client (comma-separated).

Configuring the Endpoint URLs

The <authorization-server/> element has some attributes that can be used to change the default endpoint URLs:

  • authorization-endpoint-url: The URL at which a request for an authorization will be serviced (defaults to /oauth/authorize). This URL should be protected using Spring Security so that it is only accessible to authenticated users.
  • token-endpoint-url: The URL at which a request for an access token will be serviced (defaults to /oauth/token). This URL should be accessible to authenticated clients.

If you use a custom filter on either of these endpoints, such as the 'ClientCredentialsTokenEndpointFilter' which allows clients to use HTTP Basic auth at the token endpoint, the 'filterProcessUrl' property must be set to your custom URL.

Configuring An OAuth-Aware Expression Handler

You may want to take advantage of Spring Security's expression-based access control. You can register a oauth-aware expression handler with the expression-handler element. Use the id of the oauth expression handler to add oauth-aware expressions to the built-in expressions.

The expressions include oauth2.clientHasRole, oauth2.clientHasAnyRole, and oath2.denyClient which can be used to provide access based on the role of the oauth client.

Resource Server Configuration

You need to supply the <resource-server/> element with an id attribute - this is the bean id for a servlet Filter that can be added to the standard Spring Security chain, e.g.

<http access-denied-page="/login.jsp" ...>
    <intercept-url pattern="/photos" access="ROLE_USER,SCOPE_READ" />
    ...
    <custom-filter ref="oauth2ProviderFilter" before="PRE_AUTH_FILTER"/>
</http>

<oauth:resource-server id="oauth2ProviderFilter" .../>

The <oauth:resource-server> definition technically loads an instance of OAuth2AuthenticationProcessingFilter. The following attributes can be applied to the resource-server element:

  • token-services-ref: The reference to the bean that defines the token services.
  • resource-id: The id for the resource (optional, but recommended and will be validated by the auth server if present)

OAuth 2.0 Client

The OAuth 2.0 client mechanism is responsible for access the OAuth 2.0 protected resources of other servers. The configuration involves establishing the relevant protected resources to which users might have access. The client also needs to be supplied with mechanisms for storing authorization codes and access tokens for users.

Managing Remote Protected Resources

The entry point into your database of protected resources is an instance of OAuth2ProtectedResourceDetails, which represents a remote resource (or collection of resources that all accept the same token). The basic idea is that you inject a protected resource into an OAuth2RestTemplate and use it as if it was a normal RestTemplate.

Managing Tokens

The OAuth2ClientTokenServices interface defines the operations that are necessary to manage OAuth 2.0 tokens for specific users. There is an in-memory implementation provided, but it's likely you'll need to implement your own service for storing the access tokens and associated authentication instances in a persistent database.

Client Configuration

For the OAuth 2.0 client, configuration is simplified using the custom spring configuration elements. The schema for these elements rests at http://www.springframework.org/schema/security/spring-security-oauth2.xsd. The namespace is http://www.springframework.org/schema/security/oauth2. You need to supply the <client/> element with an id attribute - this is the bean id for a servlet Filter that can be added to the standard Spring Security chain, e.g.

<http access-denied-page="/login.jsp" ...>
    <intercept-url pattern="/photos" access="ROLE_USER,SCOPE_READ" />
    ...
    <custom-filter ref="oauth2ClientFilter" after="EXCEPTION_TRANSLATION_FILTER"/>
</http>

<oauth:client id="oauth2ClientFilter" .../>

The client element is used to configure the OAuth 2.0 client mechanism. The following attributes can be applied to the client element:

  • redirect-strategy-ref: The reference to the redirect-strategy bean. Default value is an instance of DefaultRedirectStrategy.

Protected Resource Configuration

Protected resources can be defined using the resource configuration element. Each resource element is effectively a definition of a bean that is an instance of OAuth2ProtectedResourceDetails. The resource element supports the following attributes:

  • id: The id of the resource. The id is only used by the client to lookup the resource; it's never used in the OAuth protocol. It's also used as the id of the bean.
  • type: The type (i.e. "grant type") of the resource. This is used to specify how an access token is to be obtained for this resource. Valid values include "authorization_code", "implicit" and "client_credentials" (creates an instance of AuthorizationCodeResourceDetails, ImplicitResourceDetails or ClientCredentialsResourceDetails, respectively). The default creates an instance of BaseOAuth2ProtectedResourceDetails.
  • client-id: The OAuth client id. This is the id by with the OAuth provider is to identify your client.
  • client-secret: The secret associated with the resource. By default, no secret will be supplied for access to the resource.
  • access-token-uri: The URI of the provider OAuth endpoint that provides the access token.
  • user-authorization-uri: The URI to which the user will be redirected if the user is ever needed to authorize access to the resource. Note that this is not always required, depending on which OAuth 2 profiles are supported.
  • scope: Comma-separted list of string specifying the scope of the access to the resource. By default, no scope will be specified.
  • client-authentication-scheme: The scheme used by your client to authenticate to the access token endpoint. Suggested values: "http_basic" and "form". Default: "http_basic". See section 2.1 of the OAuth 2 spec.

Accessing Protected Resources

Once you've supplied all the configuration for the resources, you can now access those resources. The suggested method for accessing those resources is by using the RestTemplate introduced in Spring 3. OAuth for Spring Security has provided an extension of RestTemplate that only needs to be supplied an instance of OAuth2ProtectedResourceDetails. To use it with user-tokens (authorization code grants) you should consider using the XML namespace shortcut <oauth:rest-template/> which creates some request and session scoped context objects so that requests for different users do not collide at runtime. Example:

<oauth:resource id="sparklr" ... />

<bean id="sparklrService" class="org....SparklrServiceImpl">
    ...
    <property name="sparklrRestTemplate">
        <oauth:rest-template resource="sparklr" />
    </property>
</bean>

Customizations for Clients of External OAuth2 Providers

Some external OAuth2 providers (e.g. Facebook) do not quite implement the specification correctly, or else they are just stuck on an older version of the spec than Spring Security OAuth. To use those providers in your client application you might need to adapt various parts of the client-side infrastructure.

To use Facebook as an example, there is a Facebook feature in the tonr2 application (you need to change the configuration to add your own, valid, client id and secret - they are easy to generate on the Facebook website).

Facebook token responses also contain a non-compliant JSON entry for the expiry time of the token (they use expires instead of expires_in), so if you want to use the expiry time in your application you will have to decode it manually using a custom OAuth2SerializationService.

Customizations Not Explicitly Supported by Namespace

The XML DSL has extension points for the most common use cases, generally specified through strategies injected through attributes (e.g. the user-approval-handler-ref in the <authorization-server/>), but occasionally you may need to add customizations not supported in this way. Other cases can be handled locally without losing the benefit of the namespace because the bean definitions created are all designed to be easy to override. The namespace parsers create bean definitions with fixed bean definition names (hopefully easy to guess, but it is not hard to verify them by reading the source code of the parsers), and all you need to do to override one part of the namespace support is create a bean definition with the same name. For instance, the <authorization-server/> element creates both an AuthorizationEndpoint and a TokenEndpoint, but if you wanted to replace one of them you could override it:

<authorization-server token-services-ref="tokenServices" client-details-services-ref="clientDetails">
    <authorization-code/>
</authorization-server>

<beans:bean id="oauth2TokenEndpoint" class="org.test.oauth.MyTokenEndpoint"/>

In this example, the explicit bean definition overrides the one created by the <authorization-server/> because of the ordering in the application context declaration (this is a standard Spring bean factory feature). Bean definitions created by the namespace parsers follow the convention that they start with "oauth2" followed by the class name of the default implementation provided by the framework (if it does not already start with "OAuth2").

Something went wrong with that request. Please try again.