OAuth for Spring Security

Beware

Unless you've got a reasonable grasp of both OAuth and Spring Security , this user guide will likely lose you. Okay, let's face it, you'll probably get lost anyway. But understanding the following will help a lot:

OAuth Provider

The OAuth provider is responsible for managing the OAuth consumers that can access its protected resources on behalf of a user. The provider does this by managing and verifying the OAuth tokens that can be used to access the protected resources. Of course, the provider must also supply an interface for the user to confirm that a consumer can be granted access to the protected resources (i.e. a confirmation page).

Managing Consumers

The entry point into your database of consumers is defined by the ConsumerDetailsService . You must define your own ConsumerDetailsService that will load ConsumerDetails by the consumer key . Note the existence of an in-memory implementation of ConsumerDetailsService .

When implementing your ConsumerDetailsService consider returning instances of BaseConsumerDetails which contains additional information about the consumer that may be useful when displaying a confirmation screen to the user.

Managing Tokens

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

  • When a request token is created, care must be taken to ensure that it is not an access token.
  • When a request token is authorized, the authentication must be stored so that the subsequent access token can reference it.
  • When an access token is created, it must reference the authentication that was used to authorized the request token that is used to create the access token.

    When creating your OAuthProviderTokenServices implementation, you may want to consider extending the RandomValueProviderTokenServices which creates tokens via random value and handles everything except for the persistence of the tokens. There is also an in-memory implementation of the OAuthProviderTokenServices that may be suitable, but note that when using the in-memory implementation a separate thread is spawned to take care of the cleanup of expired tokens.

OAuth Provider Request Filters

The requests for the tokens and for access to protected resources are handled by standard Spring Security request filters. The following filters are required in the Spring Security filter chain in order to implement OAuth:

Managing Nonces

The OAuth spec also recommends that the nonce that is supplied on every OAuth request be checked to ensure it isn't used twice for the same timestamp. In order to do this, nonces must be stored and verified on every OAuth request. The interface that is used to validate nonces is OAuthNonceServices . The default implementation, <<<ExpiringTimestampNonceServices >, does not adhere to this recommendation>>, but only validates that the timestamp isn't too old. If further assurance is required, you will need to supply your own implementation of OAuthNonceServices . Note the existence of an in-memory implementation .

Authorization By Consumer

It is sometimes required to limit access to a resource to a specific consumer or to a consumer that has specific roles. The classes in the org.springframework.security.oauth.provider.attributes package can be used to do this. Methods can be protected using the annotations in that package, and the ConsumerSecurityConfig can be supplied to the standard Spring Security filter interceptor in order to enable the annotations. Finally, the ConsumerSecurityVoter would need to be supplied to the Spring Security authentication manager.

Provider Configuration

For the OAuth provider, configuration is simplified using the custom spring configuration elements. The schema for these elements rests at http://spring-security-oauth.codehaus.org/schema/spring-security-oauth-2.0.xsd . The namespace is http://spring-security-oauth.codehaus.org/2.0 .

Three custom configuration elements are used to supply provider configuration:

  • The provider element is used to configure the OAuth provider mechanism. The following attributes can be applied to the provider element:
    • consumer-details-service-ref : The reference to the bean that defines the consumer details service. This is required if not autowired.
    • token-services-ref : The reference to the bean that defines the token services.
    • request-token-url : The URL at which a request for an unauthenticated request token will be serviced. Default value: "/oauth_request_token"
    • authenticate-token-url : The URL at which a request to authenticate a request token will be serviced. Default value: "/oauth_authenticate_token"
    • access-token-url : The URL at which a request for an access token (using an authenticated request token) will be serviced. Default value: "/oauth_access_token"
    • access-granted-url : The URL to which the user will be redirected upon authenticating a request token, but only if there was no callback URL supplied from the oauth consumer. Default value: "/"
    • authentication-failed-url : The URL to which the user will be redirected if for some reason authentication of a request token failed. Default behavior is to just issue a "401: unauthorized" response.
    • nonce-services-ref : The reference to the bean that defines the nonce services. Default is to supply an instance of org.springframework.security.oauth.provider.nonce.ExpiringTimestampNonceServices
    • support-ref : The reference to the bean that defines the provider support logic. Default is to supply an instance of org.springframework.security.oauth.provider.CoreOAuthProviderSupport
    • token-id-param : The name of the request parameter that specifies to the 'authenticate-token-url' the id of the token that is to be authenticated. Default value: "requestToken".
    • callback-url-param : The name of the request parameter that specifies to the 'authenticate-token-url' the callback URL to which the user is to be redirected upon successful authentication. Default value: "callbackURL".
  • The consumer-details-service element is used to define an in-memory implementation of the consumer details service. It takes an id attribute and an arbitrary number of consumer child elements that define the following attributes for each consumer:
    • key (required): The consumer key.
    • secret (required): The consumer secret.
    • name : The (display) name of the consumer.
    • authorities : Comma-separated list of authorities (e.g. roles) that are granted to the consumer.
    • resourceName : The name of the resource.
    • resourceDescription : The description of the resource.
  • The token-services element is a simple element that can be used to provide an in-memory implementation of the provider token services. It supports an id attribute (bean id) and a cleanupInterval attribute that specifies how often the cleanup thread should wake up (in seconds).

OAuth Consumer

The OAuth consumer is responsible for ensuring that a proper access token is acquired before attempting a request for a protected resource. OAuth for Spring Security provides request filters for ensuring that the access token is acquired and utilities for making a request for a protected resource. A consumer must be responsible for maintaing a list of protected resources that can be accessed and, like the provider, a consumer must be responsible for managing the OAuth tokens.

If you were discouraged by the complexity of implementing an OAuth provider, take heart. Implementation of an OAuth consumer is easier, partially because OAuth for Spring Security provides suitable defaults for most cases.

Managing Protected Resources

A database of protected resources that are accessible by a consumer must be provided through the ProtectedResourceDetailsService . Each protected resource must provide all information related to obtaining access to it. This includes the URL to obtain a request token, the URL to which to redirect the user for authorization, the URL at which to obtain an access token, etc. It also contains various properties that describe the provider of the protected resource. Consider the existence of the InMemoryProtectedResourceDetailsService and the BaseProtectedResourceDetails for help in creating the database of protected resources.

Managing Provider Tokens

Like the provider, the consumer must be responsible for managing the OAuth tokens. The necessary interface for managing the consumer tokens is OAuthConsumerTokenServices which are only accessible via factory method . Assuming that the consumer can leverage an active HTTP session, the default HttpSessionBasedTokenServices and HttpSessionBasedTokenServicesFactory should be adequate.

OAuth Consumer Request Filters

There is a single consumer request filter, OAuthConsumerProcessingFilter , that can be applied to the resources that require access to a remote protected resource. Put this filter in the Spring Security filter chain and supply the patterns that require access to which protected resources and you'll have access to the OAuthConsumerToken s that are required via request attribute.

Requesting Protected Resources

The OAuthConsumerSupport interface can be used to configure a request for a protected resource. The CoreOAuthConsumerSupport class is the OAuth Core 1.0 implementation of the OAuthConsumerSupport . Note particularly the readProtectedResource method and the configureURLForProtectedAccess methods.

Consumer Configuration

For the OAuth consumer, configuration is simplified using the custom spring configuration elements. The schema for these elements rests at http://spring-security-oauth.codehaus.org/schema/spring-security-oauth-2.0.xsd . The namespace is http://spring-security-oauth.codehaus.org/2.0 .

Two custom configuration elements are used to supply provider configuration:

  • The consumer element configures the OAuth consumer mechanism. It requires at least one url child element. Each url child element defines the URL patterns that require access to a protected resource. The url element supports the following attributes:
    • pattern (required): The URL pattern.
    • resources (required): Comma-separated list of the ids of the protected resources that the URL requires access to.
    • httpMethod : The HTTP method that requires access. Default is all methods.

    The consumer element also supports the following attributes:

    • resource-details-service-ref : The reference to the resource details service. This is required if not autowired.
    • oauth-failure-page : The page to which to redirect the user if a problem happens during OAuth authentication.
    • entry-point-ref : Reference to the entry point to use if a problem happens during OAuth authentication (overrides oauth-failure-page ).
    • path-type : URL path type. Default value: "ant".
    • lowercase-comparisons : Whether to use lowercase comparisons.
    • support-ref : Reference to the OAuth consumer support logic.
    • token-services-factory-ref : Reference to the token services factory.
  • The resource-details-service element configures an in-memory implementation of the resource details. It supports an "id" attribute ant an arbitrary number of resource child elements which are used to define the protected resources and support the following attributes:
    • id (required): The resource id.
    • key (required): The consumer key.
    • secret (required): The shared secret.
    • request-token-url (required): The URL to use to get the OAuth request token.
    • user-authorization-url (required): The URL to which to redirect the user to authorize the request token.
    • access-token-url (required): The URL to use to get an OAuth access token.
    • signature-method : The signature method to use (e.g. "HMAC-SHA1", "PLAINTEXT", etc.). Default "HMAC-SHA1".
    • user-authorization-token-param : Name of the request parameter to use to pass the value of the request token when redirecting the user to the authorization page. Default value: "requestToken"
    • user-authorization-callback-param : Name of the request parameter to use to pass the value of the callback URL when redirecting the user to the authorization page. Default value: "callbackURL"
    • accepts-authorization-header : Whether the provider accepts the HTTP authorization header. Default: "true"
    • authorization-header-realm : The "realm" for the HTTP authorization header.