Authenticate via OAuth 1.0 with Grails

with No Comments

OAuth is an open standard for authorization, commonly used as a way for Internet users to authorize websites or applications to access their information on other websites, but without giving them the passwords. Actual version of OAuth is 2.0, published in 2012. However, some services are still using OAuth 1.0/1.0a, eg Twitter, Trello, Xero, Xing, Vimeo etc. In this article I will describe how to implement integration with API which uses OAuth 1.0 with Grails.

Full information about the protocol you can find here https://tools.ietf.org/html/rfc5849. Some providers can modify a workflow, but usually you need to go through the following steps.
oauth 1.0 flow
To implement it you can use a service’s SDK (if it’s provided), some Java library or if you are really foolhardy you are able to create your own implementation, but the easiest and the fastest way is just to use the Grails OAuth plugin http://plugins.grails.org/plugin/desirable-objects/desirableobjects.grails.plugins:oauth. This plugin is based on the old version of the Scribe Java library https://github.com/scribejava/scribejava/.

I will implement an integration with the Bitbucket Cloud API https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html#OAuthonBitbucketCloud-OAuth1.0. The Bitbucket Cloud API offers OAuth 2.0 or 1.0 to access resources, I recommend that you should use the OAuth 2.0 version, but for the example I will implement integration with the OAuth 1.0 version.

Let’s start.

  • Put compile ‘org.grails.plugins:oauth:3.0.1’ to an app dependencies for adding the plugin to your app.
  • Create an OAuth key and secret, look up for more information in provider docs.
  • Add a couple of lines to an App config.
    https://gist.github.com/KacT9H/bc873b785624723a481d50b20e221e49
  • Implement a provider API. Extend the DefaultApi10a class.
    https://gist.github.com/KacT9H/b544d542d76a359200e59b0cae559b30
  • Add a link for connection on UI. You can use provided ‘oauth ‘ TagLib for it. In my case, it looks like <oauth:connect provider="bitbucket">Connect to Bitbucket</oauth:connect>.

Congratulations, that is it!

When the user clicks to connect the link, the app obtains a request token and redirects the user to an authorization page. The user logins and thus allows access to his/her personal data for the app and a provider (in my case Bitbucket) redirects the user back to the app. Bitbucket returns in the redirect an oauth_verifier along with the oauth_token your application provided in its request. Finally, the app obtains an access token using the oauth_verifier and the request token.

Then you can get the access token from a session session[oauthService.findSessionKeyForAccessToken("bitbucket")] and store it to a DB. With the access token the requests are sent to the API oauthService.getBitbucketResource(accessToken, "https://api.bitbucket.org/1.0/user").

Perhaps, you noticed that the request a request token, the request an access token and all requests to API should be signed, a request or a header should contain specific params, e.g. an oauth_token, an oauth_signature, an oauth_timestamp etc. Fortunately, the OAuth plugin provides the OAuth10aServiceImpl service which has methods for signing requests with OAuth 10 rules, so I just set Request Token and Access Token Endpoints and the Authorization Url.

Possibly, you will need to implement integration with a service which makes a slight change to default workflow, e.g. a signature generation algorithm. In this case, you can extend the OAuth10aServiceImpl service and override the API’s createService method.

P.S.
Grails version is 3.2.4.
Grails Oauth Plugin version is 3.0.1.

Leave a Reply