Security Global Forum

Security Global Forum

Our mission is to provide clients with an online user community of industry peers and IBM experts, to exchange tips and tricks, best practices, and product knowledge. We hope the information you find here helps you maximize the value of your IBM Security solutions.

 View Only

Mobile Demonstration – Under the Hood

By Shane Weeden posted Fri December 23, 2011 12:00 AM

  

TFIM OAuth Mobile Demonstration – Under the hood

In my previous article I presented a demonstration of a mobile application retrieving a protected resource (a set of user profile attributes) from a website using OAuth 2.0. In this article I’ll explain the rationale for using OAuth 2.0, show you the exact message transactions used by that application and present some of the variables you need to consider when making design/deployment decisions for such an environment. An understanding of the OAuth 2.0 Protocol and the Bearer Token Specification is an advantage when reading this article.

Why use OAuth 2.0

I believe the number one reason for using OAuth 2.0 as opposed to alternative security protocols is its relative ease of use for client application developers. By lowering the technical entry point for client developers you have the opportunity to reach more customers. Sure, developers can still get it wrong by not following security best practices such as requiring secure transport with server certificate validation, storing keys insecurely, etc, but these flaws are possible with other protocols as well. Given that those baseline best practices are followed, writing OAuth 2.0 clients is really trivial.

OAuth 2.0 is also an emerging standard with widespread adoption and this means that client application developers will be increasingly seeing the same deployment patterns time and again allowing for code re-use, client library development which does incorporate security best practices, etc. Being a standard is a good thing.

Messages used for the Mobile Demonstration Application

In this section I will show you exactly how the mobile application communicates with the TFIM demonstration site. You can “be a mobile phone app” with just a few simple curl commands.

For the technically minded comfortable with OAuth 2.0, here’s the key information you’d need to develop the mobile application:

  • The client type is public, with the client_id: mobileClient. This means there is NO client_secret.
  • The authorization code flow is used with simple bearer tokens. The authorize endpoint is: https://tfim01.demos.ibm.com/FIM/sps/oauth20sp/oauth20/authorize
  • There is no redirect_uri registered at the service provider, and none should be passed to the authorize endpoint. Instead the authorization code will be displayed on the browser and the user will manually deliver it to the client. There are alternatives to this such as custom scheme registration, back-channel delivery of the authorization code via a notification service, the device code flow, etc. Manual delivery was chosen in this deployment for simplicity. Make no mistake though, secure delivery of the authorization code is fundamental to the security of the system.
  • Passing scope to the authorize endpoint is optional. If no scope is passed, the user will be asked to authorize all their available profile attributes. If scope is passed, each scope string represents an attribute name the client is requesting permission to access.
  • The token endpoint is: https://tfim01.demos.ibm.com/FIM/sps/oauth20sp/oauth20/token
  • When an authorization code is presented to the token endpoint, the JSON response will contain the standard OAuth 2.0 response parameters plus one additional string parameter called appInstance with the value being the friendly name the user chose for their application instance during authorization. The client should use this for display purposes to allow the user to reconcile the application instance with their list of registered instances on the service provider management site.
  • The access token lifetime is 1 hour. This is also reflected using the expires_in response parameter from the token endpoint.
  • Refresh tokens are used, and are rolled over to a new value on each use. Refresh tokens do not expire, but are single-use as just described.
  • When a refresh token is used to get a new access token, the old access token becomes invalid immediately. This means there is only one active valid access token at any given time.
  • There is only one protected resource URL and it takes no request parameters other than the access token. The access token can be delivered via authorization header, post body or query string per the bearer token spec. The protected resource accepts both GET and POST http methods, and the resource URL is: https://tfim01.demos.ibm.com/FIM/demo/oauthprotected/profile.jsp
  • The successful protected resource response is a 200 OK followed by a JSON string containing two fixed fields, and variable fields for the user profile data. The fixed fields are:
    username The username of the resource owner who issued the grant
    timestamp The current time as milliseconds since epoch – i.e. (new java.util.Date()).getTime()

    The variable fields are all JSON string arrays as attributes can be multi-valued. An example protected resource response can be seen later in this article.

Let’s get started!

Obtaining an authorization code

This step requires the resource owner to use a browser at the service provider. Here’s the URL: https://tfim01.demos.ibm.com/FIM/sps/oauth20sp/oauth20/authorize?client_id=mobileClient&response_type=code

Remember scope is optional and you can explicitly added something like scope=attr1 attr2 to the parameter list. Following authentication and authorization, the resource owner will see the authorization code on the screen of the service provider, and manually provides it to the client.

This screenshot shows the authorize step where the user decides which attributes to grant access to, and assigns a friendly name for the application instance:

This screenshot shows the authorization code displayed with a reminder that it expires in 60 seconds:

Exchanging an authorization code for an access token and refresh token

The client obtains the authorization code from the resource owner, and exchanges it for an access token and refresh token. The appInstance (friendly name chosen by the user for the application instance) is also returned in the response from the token endpoint. This exchange must be completed within 60 seconds of the authorization code being displayed to the resource owner:

curl -d "client_id=mobileClient&grant_type=authorization_code&code=cioyus" 
    https://tfim01.demos.ibm.com/FIM/sps/oauth20sp/oauth20/token

{"expires_in":3599,"scope":"email phone","appInstance":"myphone","access_token":"aHWynpQiUYsJ4C4jLJpg",
    "token_type":"bearer","refresh_token":"WtFQMWtU88cRdxNoCYl8FJwU7wiAnLbrY0peYSWa"}

If the exchange is not completed within 60 seconds the authorization code expires and the resource owner simply has to get a new one following the same procedure.

Using the access token to request the protected resource

The protected resource can be retrieved with an access token three different ways. All result in the same response:

Using the access token in an Authorization header

curl -H "Authorization: Bearer aHWynpQiUYsJ4C4jLJpg" https://tfim01.demos.ibm.com/FIM/demo/oauthprotected/profile.jsp

Using the access token as a POST body parameter

curl -d "access_token=aHWynpQiUYsJ4C4jLJpg" https://tfim01.demos.ibm.com/FIM/demo/oauthprotected/profile.jsp

Using the access token in a query string

curl https://tfim01.demos.ibm.com/FIM/demo/oauthprotected/profile.jsp?access_token=aHWynpQiUYsJ4C4jLJpg

In each case the response for the protected resource should be the same:

{"timestamp":1324601764437,"username":"sweeden@au1.ibm.com",
    "email":["sweeden@au1.ibm.com"],"phone":["55512345","55554321"]}

Using a refresh token to get a new access token and refresh token

When the access token expires, or the application instance has been disabled and then re-enabled at the service provider management interface by the resource owner, the client will get an error when trying to use the access token to get a protected resource. Instead of a 200 OK response with JSON data, a 401 response will be returned, as shown:

curl -v -H "Authorization: Bearer aHWynpQiUYsJ4C4jLJpg" https://tfim01.demos.ibm.com/FIM/demo/oauthprotected/profile.jsp
> GET /FIM/demo/oauthprotected/profile.jsp HTTP/1.1
> User-Agent: curl/7.22.0 (i686-pc-cygwin) libcurl/7.22.0 OpenSSL/0.9.8r zlib/1.2.5 libidn/1.22 libssh2/1.2.7
> Host: tfim01.demos.ibm.com
> Accept: */*
> Authorization: Bearer aHWynpQiUYsJ4C4jLJpg
> 
< HTTP/1.1 401 
< content-type: text/html
< p3p: CP="NON CUR OTPi OUR NOR UNI"
< www-authenticate: Bearer realm="https://tfim01.demos.ibm.com"
< x-old-content-length: 17
< transfer-encoding: chunked
< 
<html>401</html>

The client must then use the refresh token to obtain a new access token:

curl -d "client_id=mobileClient&grant_type=refresh_token&refresh_token=WtFQMWtU88cRdxNoCYl8FJwU7wiAnLbrY0peYSWa" 
    https://tfim01.demos.ibm.com/FIM/sps/oauth20sp/oauth20/token

{"expires_in":3599,"scope":"email phone","access_token":"GrYWuLN2o3H1QNEfuoVk",
    "token_type":"bearer","refresh_token":"GKibcdQrQ9piPxtOzh1iM1KnFfVwu7B5BLHd5AHZ"}

If the client receives an error from the refresh token request that is not a communications error, a severe warning should be displayed to the user as one of the following has happened:

  • The resource owner has disabled or deleted the application instance at the service provider.
  • The refresh token has been compromised and used by an attacker.

The resource owner should told to login to the service provider at the Manage Mobile Applications page and if the application instance is shown as enabled it should be immediately deleted to revoke access to the attacker who has compromised the refresh token. Re-registration of the application is then possible by beginning with a new authorization code.

Deployment Considerations

When designing this demonstration scenario there were a lot of variables for deployment that were taken into consideration. These include:

  • Entropy, lifetime and delivery mechanism of the authorization code. Ultimately we chose manual delivery for simplicity. Therefore we wanted the length to be reasonably short, and chose 6 lower case characters for easy entry into a mobile phone keyboard. As the authorization code is short, a short lifetime was used to reduce attack exposure windows since no client secret is needed to present it to the token endpoint.
  • Lifetime and entropy of access tokens. These can be anything you like, we chose an hour for lifetime and 20 alphanumerics for an access token.
  • Lifetime and entropy of refresh tokens. In our scenario we made the lifetime of a refresh token infinite, and the length of a refresh token 40 alphanumerics. Again this comes down to personal choice. Longer refresh tokens are simply a configuration choice. The reason we chose to make refresh tokens of infinite lifetime is that when the refresh token expires, re-registration of the application instance is the only option. This may be ok depending on your own use case requirements.
  • Concurrency of tokens. In our scenario only one access token and refresh token may be valid at a time per authorization grant. This is quite suitable since the access token and refresh token represent a single instance of the application stored on a phone.

The mobile application scenario is implemented on the server side using Tivoli Federated Identity Manager with a modified version of the OAuth JDBC plugins that I have previously made available, along with a custom Java mapping rule for the OAuth federation that communicates with the database tables used for token storage. Tivoli Access Manager WebSEAL is used as the point of contact, and the WebSEAL enforcement point for OAuth is used for access token validation.

I hope this article helps to explain the value OAuth offers to companies wishing to expose resources and API’s for client applications to call on behalf of your users. Should you have any questions about this scenario or your own business scenario and are considering Tivoli Federated Identity Manager, please contact me.

0 comments
5 views

Permalink