Exchanging An OAuth2 Access token for An OpenAM Cookie (Cookie base OAuth2 grant)

OpenAM provides a set of REST APIs to authenticate the users with username/password & validates the authenticated user’s sessions.  Assume that there is an application which has been implemented to authenticate its end users by calling REST API of the OpenAM.

As an example in following HTTP POST request must be sent to OpenAM for authenticating the users.

 curl -X POST -H "X-OpenAM-Username: asela" -H "X-OpenAM-Password: mypassword" -H "Content-Type: application/json" http://localhost:8080/openam/json/realms/root/authenticate

Once user is authenticated, OpenAM will create an end user session & return the related session token as the response.

{"tokenId":"AQIC5wM2LY4Sfcx8KG5UZGwMq8mB7Pu8k2HMI1tTI2oUGLA.*AAJTSQACMDEAAlNLABQtMTkwNTYzMDM0MjY1NDM4MzA5OQACUzEAAA..*","successUrl":"/openam/console","realm":"/"}

If application needs to invoke APIs which are protected with OAuth2 on behalf of the authenticated user,  application needs to exchange this session token for OAuth2 access token.

If OAuth2 authorization server is WSO2IS or WSO2 APIM, then we can easily achieve the token exchange by implementing an OAuth2 custom grant type

You can find my previous post of implementing custom grant type for WSO2IS/WSO2APIM OAuth2 Authorization server from here.

In this post,  lets see how we can implement OpenAM cookie based grant type.

Step 1 .  Identify the way to validate the OpenAM cookie & retrieve user’s information which is related to the cookie.

This can be achieved by using following REST API which is given by OpenAM.

Curl command for REST API

curl -X POST -H "Content-Type: application/json" -H "iplanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" http://localhost:8080/openam/json/realms/root/sessions/?_action=getSessionInfo

If cookie is valid, JSON response is returned as following.

{
"username": "asela",
"universalId": "id=asela,ou=user,dc=openam,dc=forgerock,dc=org",
"realm": "/",
"sessionHandle": "shandle:AQIC5wM2LY4Sfcxs...EwNDU2NjE0*",
"latestAccessTime": "2017-02-16T17:03:06Z",
"maxIdleExpirationTime": "2017-02-16T17:33:06Z",
"maxSessionExpirationTime": "2017-02-16T19:03:05Z"
}

Therefore we can implement this logic in our custom grant handler to validate the cookie & retrieve user’s attributes.

Step 2. Implement custom grant handler

You can find the custom grant implementation from here

You can clone it & use build using maven 3.

Step 3. Deploy & Register custom grand handler with WSO2IS & APIM.

You can copy built JAR file in to  /repository/components/lib directory.

If you are using WSO2IS, you can register it by adding following configuration in to identity.xml file under <SupportedGrantTypes> tag

<SupportedGrantType>
<GrantTypeName>openamcookie</GrantTypeName>
<GrantTypeHandlerImplClass>org.soasecurity.wso2.oauth2.openam.cookie.grant.OpenAMCookieGrantHandler</GrantTypeHandlerImplClass>
<GrantTypeValidatorImplClass>org.soasecurity.wso2.oauth2.openam.cookie.grant.OpenAMCookieGrantValidator</GrantTypeValidatorImplClass>
<OpenAMSessionEndpoint>http://localhost:8080/openam/json/realms/root/sessions/?_action=getSessionInfo</OpenAMSessionEndpoint>
</SupportedGrantType>

<OpenAMSessionEndpoint> value must be configured based on your OpenAM session info endpoint.  Default value would be following

http://localhost:8080/openam/json/realms/root/sessions/?_action=getSessionInfo

If you are using WSO2 APIM, Please change <GrantTypeHandlerImplClass> to following.

<GrantTypeHandlerImplClass>org.soasecurity.wso2.oauth2.openam.cookie.grant.ExtendedOpenAMCookieGrantHandler</GrantTypeHandlerImplClass>

After above, you need to restart the server & create an OAuth2 application using APIM store & WSO2IS management console.

You need to select new grant type as allowed grant type for created application.

Step 4. Try out.  Following is the sample HTTP POST request you need to send in to the /token endpoint.

curl -k -v -X POST -u fdowKYyXzX_01WsjSfiP0ZCgm8Ia:X_Sl5vdVtakDxCp2iWm9wKu4HAca -d "grant_type=openamcookie&cookie=AQIC5wM2LY4SfcwIW5ufU1quxPgo9l01LLH1Tlh5HQU3qi4.*AAJTSQACMDEAAlNLABM2OTUwOTk4MzY1NjMxMTUyMDA3AAJTMQAA*" https://localhost:9443/oauth2/token

In above request cookie has been send as POST body parameter with grant type parameter. Also client id/secret must be sent as basic authentication headers.

OAuth2 authorization server will repose back with access token.  Now you can exchange the cookie for an access token.

Thanks for reading!