2 Getting Started - Reference Documentation
Authors: Brian Saville, Bobby Vandiver, Roy Willemse
Version: 3.0.0-RC2
Table of Contents
2 Getting Started
The following assumes that the Spring Security Core plugin has been installed and its required domain class created.2.1 Install Plugin
Install the OAuth2 plugin by adding a dependency inbuild.gradle
:dependencies { compile 'org.grails.plugins:spring-security-oauth2-provider:3.0.0-SNAPSHOT' }
2.2 Create Domain Classes
Run the s2-init-oauth2-provider script to generate the required domain classes.2.3 Secure Authorization and Token Endpoints
Update the Core plugin's rules for the authorization and token endpoints so they are protected by Spring Security. If you're using the Core plugin'sstaticRules
, you'll want to add the following in grails-app/conf/application.groovy
:grails.plugin.springsecurity.controllerAnnotations.staticRules = [ [pattern: '/oauth/authorize', access: "isFullyAuthenticated() and (request.getMethod().equals('GET') or request.getMethod().equals('POST'))"], [pattern: '/oauth/token', access: "isFullyAuthenticated() and request.getMethod().equals('POST')"], ...
.dispatch
.The additional restrictions on the allowed HTTP methods are to ensure compliance with the OAuth 2.0 spec as defined in RFC 6749.
2.4 (Optional) Customize Error and Confirm Access Views
The plugin provides views for the error and confirm access pages. These can be overridden by providing your owngrails-app/views/oauth/error.gsp
and grails-app/views/oauth/confirm_access.gsp
files, respectively.
2.5 Client Registration
At this point your application is a proper OAuth 2.0 provider. You can now register clients in what ever method is appropriate for your application. For example, you can register a client ingrails-app/init/Bootstrap.groovy
as follows:def init = { servletContext -> new Client( clientId: 'my-client', authorizedGrantTypes: ['authorization_code', 'refresh_token', 'implicit', 'password', 'client_credentials'], authorities: ['ROLE_CLIENT'], scopes: ['read', 'write'], redirectUris: ['http://myredirect.com'] ).save(flush: true) }
2.6 Controlling Access to Resources
Access to resources is controlled by the Spring Security Core plugin's access control mechanisms. Additionally, the plugin has full support for the OAuth 2.0 SPeL extensions provided by the underlying Spring library. Refer to the methods in OAuth2SecurityExpressionMethods for what is available in the plugin.Using SPeL is the only tested and confirmed way to enforce OAuth 2.0 specific restrictions on resource access.The following controller illustrates the use of OAuth 2.0 SPeL:class SecuredOAuth2ResourcesController { @Secured(["#oauth2.clientHasRole('ROLE_CLIENT')"]) def clientRoleExpression() { render "client role expression" } @Secured(["ROLE_CLIENT"]) def clientRole() { render "client role" } @Secured(["#oauth2.clientHasAnyRole('ROLE_CLIENT', 'ROLE_TRUSTED_CLIENT')"]) def clientHasAnyRole() { render "client has any role" } @Secured(["#oauth2.isClient()"]) def client() { render "is client" } @Secured(["#oauth2.isUser()"]) def user() { render "is user" } @Secured(["#oauth2.denyOAuthClient()"]) def denyClient() { render "no client can see" } @Secured(["permitAll"]) def anyone() { render "anyone can see" } def nobody() { render "nobody can see" } @Secured(["#oauth2.clientHasRole('ROLE_TRUSTED_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('trust')"]) def trustedClient() { render "trusted client" } @Secured(["hasRole('ROLE_USER') and #oauth2.isUser() and #oauth2.hasScope('trust')"]) def trustedUser() { render "trusted user" } @Secured(["hasRole('ROLE_USER') or #oauth2.hasScope('read')"]) def userRoleOrReadScope() { render "user role or read scope" } }
grails.plugin.springsecurity.filterChain.chainMap = [ [pattern: '/oauth/token', filters: 'JOINED_FILTERS,-oauth2ProviderFilter,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-exceptionTranslationFilter'], [pattern: '/securedOAuth2Resources/**', filters: 'JOINED_FILTERS,-securityContextPersistenceFilter,-logoutFilter,-authenticationProcessingFilter,-rememberMeAuthenticationFilter,-oauth2BasicAuthenticationFilter,-exceptionTranslationFilter'], [pattern: '/**', filters: 'JOINED_FILTERS,-statelessSecurityContextPersistenceFilter,-oauth2ProviderFilter,-clientCredentialsTokenEndpointFilter,-oauth2BasicAuthenticationFilter,-oauth2ExceptionTranslationFilter'] ]
2.7 Trouble Shooting
If an instance of one of the GORM backed classes that the plugin uses cannot be saved, anOAuth2ValidationException
will be thrown. This is a subclass of the standard Grails ValidationException
so the plugin consumer has the flexibility to determine how to deal with this type of error. The typical reason for this exception being thrown will likely be related to the max size allotted to the serialized OAuth2Authentication
fields. The thrown exception can be inspected for further information about the Errors
.