OAuth2: (tiny) Intro and Authorization Code Flow

Although the OAuth2 Specification is still a working document, there are already quite a few big services out there that are using OAuth2 as their authentication and authorization framework of choice: Foursquare, Facebook, Twitter (although v1)… just to name a few.  As hybris offers the OCC Web Services, a set of RESTful Web Services targeted at allowing clients (mobile, other frontends, POS-systems), we also started thinking about adding OAuth2 and even making it our default 3rd party authentication protocol. We currently have a fully integrated hybris system running with Spring Security’s OAuth2 module and will investigate it over the next weeks.

OAuth2 is not really hard to understand, but the orchestration of the various requests and redirects can appear a bit complex. Adding to that, the mentioned services such as Facebook all implement just a part of the full specification and sometimes do things differently than specified (at some point they just needed to release an OAuth API, while the spec has naturally progressed and changed).

So in this first blog post (as part of an OAuth2 Series), I’ll try to shed some light on OAuth2, step by step. We’ll start with a brief overview of the available flows and then look into the most important flow, the Authorization Grant Flow.

So what flows are there? Well, 4. Some are suited well for server-side web applications, while others are better for native mobile applications. Here they are:

  • Authorization Code Flow, aka Server-Side Flow or the ‘typical’ Oauth2 flow: this flow includes sending the client user via redirect to the provider’s login and authorization page, then will redirect back to your web application and pass a authorization code in the URL parameters. You can then exchange this for an access token which you need to pass on in your HTTP Request Headers to obtain access to the user’s data. This flow is great if your code can keep a secret, the client_secret, for example in some server-side code. With the access token, you also get a refresh token and information about the expiry of the access token. You can exchange a refresh token that you saved in your database at a later point against a new access token for long-lived access.
  • Implicit Flow, aka as Client-Side Flow: this flow is pretty simple and is suited for browser-based client-side web applications. This means: JavaScript. You send the user via redirect to the provider’s web site, she logs in and authorizes your app, then the provider redirects back to your web application. The access token is directly passed in the URL #hash and can be extracted with a little JavaScript code. As the client is not able to keep a secret, there is none (no client_secret). Also, there is no such things as refresh tokens, the client web app will have to ask for a new token.
  • Resource Owner Password Flow: the unknown. No, really. When I first found out about that flow, I thought it is pretty close to Basic Authentication, but it has a few benefits that are worth using it. This flow is great for native mobile applications *you can trust*, e.g. if you have a contractual agreement with the mobile app developer for example. This flow includes sending the user’s username and password to the token endpoint in exchange for an access token. While replying with a refresh token is optional, it should really be included, as the mobile client otherwise has to keep the user’s username and password for long-lived access. So what again is the benefit over Basic Authentication? The (mobile) client does not have to keep the username and password. Instead it can keep the access token for the current user session and later use the saved refresh token for obtaining a new access token. This one happens to fit best to a typical mobile application that might want to access the hybris OCC Web Services, as our customers will typically only allow a preselected list of developers access to the web services (e.g. an Android dev, an iOS dev, etc.)
  • Client Credentials Flow: this flow is currently not supported by our APIs, as it is meant to give the client itself access to resources it owns. It identifies the client and does not give the client access to users’ data. It is very simple and involves also just one request and response pair.

Let’s now spend more time with the Authorization Code Flow, best suited for server-side web applications. This is the flow as per OAuth2 spec (copied out of the spec):

Source: OAuth2 Spec,  http://tools.ietf.org/id/draft-ietf-oauth-v2-26.html#grant-code

Step-by-Step:

(A) Redirect the user to the Authorization Server, the authorization endpoint (typically /oauth/authorize). All communication should be via HTTPS so no one can read the client_secret out of the URL. You have to include a few parameters:

  • response_type: the value here needs to be code, as we’re using the authorization code flow.
  • client_id: for hybris’ Web Services, an OAuth2 client has to be manually setup in the Spring Security OAuth2 XML Configuration. As a client developer, this will be given to you.
  • client_secret: the ‘secret’ for the client_id – as the same should show: keep this secret. Put it into the server-side code that no user will ever see.
  • redirect_uri: while it is optional, we recommend to specify the single redirect URI in the authorization server configuration for this client. When you redirect the user to the authorization endpoint, you also have to pass this value, plus it has to match the server configuration setting.
  • scopes: this may be a space-delimited list of scopes. Scopes can be used to allow different levels of access. For our purposes at hybris, we’ll initially have no scope or just one scope, the ‘customer’ scope. That means a client can get access to a customer’s data.
  • state: again optional, but ideally you should calculate some pseudo-random state and store it under the user’s session before redirecting the user to the authorization endpoint. Once access has been granted, the redirect back to your web appliation will include the same state parameter which you can compare to rule out CSRF (cross-site request forgery) attacks.

Sounds a lot? It’s actually pretty easy in code. To test our implementation, we’ve used a local Google App Engine Web Application running the light-weight Gaelyk Framework. It allows us to quickly prototype a potential client application for our OAuth2 server. Gaelyk is  MVC-style and Controllers are written in Groovy code. So here it is:

 (B) The user authenticates herself and grants authorization. This is sometimes a two-step process, as the /oauth/authorize endpoint itself is secured via – let’s say Basic Authentication. This means if the user is not logged into your main web application (think not logged into Facebook), she will first see the log in screen. After this step, she has to grant access to your mobile client: Would you like to grant access to ‘mobile_android’? Let’s assume the answer is yes.

(C)  The Authorization Server now redirects back to your web application, passing a few parameters in the URL as request parameters. There’s nothing to do so far on the client developer side. The paramters that get passed in this redirect to your app are these:

  • code: as the grant_type was set to code, you get access to an authorization code. Later, you’ll use the code to request an acces token.
  • state: the state parameter that you specified in the first redirect to the Authorization Server. You should check with the session if the value is the same.

(D) Your web application verifies the redirect and exhanges the authorization code for an access token. Again, we can show you how this is done in our demo client code:

You can see that we first verify that there is a code and state parameter. We also verify that the state we have in the user’s session is the same as the one that got passed in the redirect from the Authorization Server.

We then make the final request to obtain an access token. The URL now points to the token endpoint (we first used the authorization endpoint). We again pass a few parameters:

  • code: of course, we have to pass the authorization code that we just obtained
  • grant_type: this is now set to authorization_code. It tells the token endpoint we want the real thing, the access token.
  • redirect_uri: again, we also pass the redirect_uri. This will not be used for an actual redirect at this point, but again checked for consistency.
  • client_id and client_secret: to identify our client application

(E) Finally, an access token! Yay! We did it. In the above example we simply print the complete server response to out, the response printwriter. The response you can expect looks like this:

As per the OAuth2 spec, it’s supposed to be a JSON-formatted text and luckily the hybris OAuth2 prototype will also give you that. Some implementations, such as Facebook’s for example will unfortunately return a different response. But in our case, you can now simply parse the String into a JSONObject and extract the access_token. The expires_in key in the JSON response tells you in how many seconds from now the access token will expire. You should save this information along with the refresh_token to later exchange the refresh token into a fresh access token.

Let’s see how me make a simple authenticated request using the OAuth2 access token (again, Groovy Code… we love Groovy):

That’s it, we just accessed a hybris customer profile using OAuth2!

My next blog post will be a short one about refreshing an expired access token, e.g. we’ll gonna use the refresh token to obtain a new access token. Till then I’d love to hear back from you!

 
44 Kudos
Don't
move!
Facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Leave a Reply

Your email address will not be published. Required fields are marked *