OAuth 1.0a Bounded Tokens

We had a very interesting discussion today on the $subject.

In fact, one of my colleagues came up with a question - "Why the hell OAuth 1.0 uses two keys to sign messages..? Why Not just the consumer secret ?"

Well.. In fact - the exact reverse of this argument is one key point Eran Hammer highlights in his famous blog post - to emphasize why OAuth 1.0a is better...

"Unbounded tokens - In 1.0, the client has to present two sets of credentials on each protected resource request, the token credentials and the client credentials. In 2.0, the client credentials are no longer used. This means that tokens are no longer bound to any particular client type or instance. This has introduced limits on the usefulness of access tokens as a form of authentication and increased the likelihood of security issues."

Before I answer the question - let me very briefly explain OAuth 1.0a flow..

1. To become an OAuth consumer you need to have a Consumer Key and a Consumer Secret. You can obtain these from the OAuth Service Provider. These two parameters can be stored in a database or in the filesystem.

Consumer Key: A value used by the Consumer to identify itself to the Service Provider.
Consumer Secret: A secret used by the Consumer to establish ownership of the Consumer Key.


2. Using the Consumer Key and Consumer Secret, you need to talk to the OAuth Service Provider and get a Unauthorized Request Token.

Request to get the Unauthorized Request Token will include following parameters.
  • oauth_consumer_key
  • oauth_signature_method
  • oauth_signature
  • oauth_timestamp
  • oauth_nonce
  • oauth_version
  • oauth_callback
Here the certain parameters of the request will be signed by the Consumer Secret. Signature validation at the OAuth Service Provider end will confirm the identity of the Consumer.

As the response to the above token, you will get the following.
  • oauth_token
  • oauth_token_secret
  • oauth_callback_confirmed
Here, the oauth_token is per OAuth Consumer per Service Provider. But can only be used once. If an OAuth consumer tries to use twice, OAuth Service Provide should discard the request.

3. Now the OAuth Consumer, has the Request Token - and it needs to exchange this token to an Authorized Request Token. The Request Token needs to be authorized by the end user. So, the Consumer will redirect the end user to the Service Provider with following request parameter.
  • oauth_token
This oauth_token is the Request Token obtained in the previous step. Here there is no signature - and this token does not need to be signed. The token it self proves the identity of the OAuth Consumer.

As the response to the above, OAuth Consumer will get the following response.
  • oauth_token
  • oauth_verifier
Here, the oauth_token is the Authorized Request Token. This token is per User per Consumer per Service Provider.

The oauth_verifier is a verification code tied to the Authorized Request Token. The oauth_verifier and Authorized Request Token both must be provided in exchange for an Access Token. They also both expire together. If the oauth_callback is set to oob in Step 2, the oauth_verifier is not included as a response parameter and is instead presented once the User grants authorization to Consumer Application. The Service Provider will instruct the User to enter the oauth_verifier code in Consumer  Application. The Consumer must ask for this oauth_verifier code to ensure OAuth authorization can proceed. The oauth_verifier is intentionally short so that a User can type it manually.

Both the above two parameters are returned back to the OAuth Consumer via a browser redirect over SSL.

4. Now the OAuth Consumer has the Authorized Request Token. Now it will exchange that to an Access Token. Once again the Access Token is per User per Consumer per Service Provider. Here the communication is not a browser re-direct but a direct communication between the Service Provider and the OAuth Consumer. This step is needed because, in step 3, OAuth Consumer gets the token through the browser.

The request to the access token will include following parameters.
  • oauth_consumer_key
  • oauth_token
  • oauth_signature_method
  • oauth_signature
  • oauth_timestamp
  • oauth_nonce
  • oauth_version
  • oauth_verifier
Here the oauth_token is the Authorized Request Token from step - 3.

The signature here is generated using a combined key - Consumer Secret and Token Secret [from step -2 ] separated by an "&" character. I will explain later why two keys used here for signing.

As the response to the above, the Consumer will get the following...
  • oauth_token
  • oauth_token_secret
All four steps above should happen over TLS/SSL.

5. Now the OAuth Consumer can access the protected resource. The request will look like following.
  • oauth_consumer_key
  • oauth_token
  • oauth_signature_method
  • oauth_signature
  • oauth_timestamp
  • oauth_nonce
  • oauth_version
Here the oauth_token is the Access Token obtained in step-4. The signature is once again generated by a combined key. Consumer Secret and Token Secret [from step -4 ] separated by an "&" character.

The step - 5 does not required to be on TLS/SSL.

Let's get back to the original question...

Why the hell OAuth 1.0 uses two keys to sign messages..? Why Not just the consumer secret ?

During the OAuth flow there are three places where OAuth Consumer has to sign.

1. Request to get an Unauthorized Request Token. Here the request will be signed by the Consumer Secret only. ( Request for Temporary Credentials )

2. Request to get an Access Token. Here the request will be signed by the Consumer Secret and the Token Secret returned back with the Unauthorized Request Token in step - 2. ( Request for Token Credentials )

Why do we need two keys here ? It's for tighten security. What exactly that means..?

Have a look at step - 3. There the Consumer only sends the oauth_token from step - 2 to get User authorization. And as the response to this the Consumer will get the Authorized Request Token (oauth_token). Now in step - 4 Consumer uses this Authorized Request Token to get the Access Token. Here, the consumer needs to prove that - its the same consumer who got the unauthorized request token, now requesting for the Access Token. To prove the ownership of the Request Token, now the Consumer will sign the Access Token request with both the Consumer Secret and the Token Secret returned back with the Unauthorized Request Token.

3. Request to the protected resource. Here the request to the protected resource will be signed by the Consumer Secret and the Token Secret returned back with the Access Token in step - 4. ( Request for Resources )

Once again we need two keys here for tighten security. If OAuth only relies on the consumer secret for the signature, the person who steals can capture the access token [as it goes to the protected resource on HTTP] and signs the request with the stolen secret key. Then all the users of that OAuth Consumer will be compromised. Since we use two keys here, even though someone steals the consumer secret it cannot harm any of the end users - because it cannot get the Token Secret which is sent to the Consumer over SSL in step - 4. Also - you should never store Token Secrets at the Consumer end - that will reduce any risks of stealing Token Secrets. But, you need to store your Consumer secret as explained previously.

In any case if you have to store the Token Secret, then you need store it encrypted - and also make sure you store it in a different database from where you store your consumer secret. That is the best practice we follow when we store hashed passwords and the corresponding salt values.

Apart from the above benefit - the Token Secret can also act as a salt value. Since the request to the protected resource goes over the wire, a hacker can carry out a known plain text attack to guess the Key used to sign the message. If we only use the Consumer Secret, then all the users of the OAuth Consumer will be compromised. But, if we use the Consumer Secret with the Token Secret, then only that particular user will be compromised - not even the Consumer Secret.

Finally, OAuth presents a Bounded Token protocol over HTTP for accessing the protected resource. That means - each request to the protected resource the Conumer should prove that he owns the token, as well as - he is the one who he claims to be. In the bounded token model, an issued token can only be used by the exact person who the token was issued to. [Compare this with Bearer token in OAuth 2.0]. To prove the identity of the Consumer it self, it can sign the message it self with consumer_secret. To prove that he also owns the token, he needs to sign the message token_secret too. Anyone can know the Access Token, but it's only the original Consumer knows the token_secret. So the key to sign is derived from combining both the keys.

Security Patterns : Decentralized Federated SAML2 IdPs

Say you are a globally distributed enterprise with thousands of branches. Each branch has it's own user store and manages it's own users. Also, each branch hosts it's own web applications. The questions is, how to enable single sign-on across branches in a highly scalable manner.

1. User in Domain Foo tries to access a Web App in the same domain.

2. Web App finds out that the user is not authenticated and redirects him to the SAML2 IdP in the same domain.

3. SAML2 IdP finds out that the user does not have an authenticated session and prompts him to authenticate. Once authenticated SAML2 IdP will redirect the user to the Web App with the SAML2 Response. And also writes a cookie to the user's browser under the Foo SAML2 IdPs domain.

4. Now the user from Domain Foo tries to access a Web App in Domain Bar. When the request to the Domain Bar initiated from the Domain Foo, a proxy in the Domain Foo adds a special HTTP Header [federated-idp-domain] to indicate from which domain the request being generated.

5. Web App in Domain Bar finds out the user is not authenticated and redirects to the SAML2 IdP in it's own domain [Domain Bar].

6. The SAML2 IdP in Domain Bar figures out that the user does not have an authenticated session and also reads federated-idp-domain HTTP Header and finds out from where the request was initiated and redirects the user to it's own domain - Domain Foo. Here the Domain Bar IdP creates a SAML2 Request and sends that to the SAML2 IdP in Domain Foo.

7. Domain Foo IdP checks whether the user has an authenticated session. By the cookie, Foo IdP finds out that the user is already authenticated and sends back a SAML2 Response to the SAML2 IdP in Domain Bar.

8. Bar IdP validates the SAML2 Response and redirects the user back to the Web App in Domain Bar. Now the user can log in to the Web App. Bar IdP also writes a cookie to user's browser under it's own domain.

9. Now the user from Domain Foo tries to access another Web App in Domain Bar. When the request to the Domain Bar initiated from the Domain Foo, a proxy in the Domain Foo adds a special HTTP Header [federated-idp-domain] to indicate from which domain the request being generated.

10. The Web App in Domain Bar finds out the user is not authenticated and redirects to the SAML2 IdP in it's own domain [Domain Bar].

11.  The SAML2 IdP in Domain Bar figures out that the user has an authenticated session, by checking the cookie which it wrote in step-8. User will be redirected back to the Web App with the SAML2 Response. Now the user can log in to the Web App.

With this pattern, each SAML2 IdP in each domain will trust each other and will register with each other.

Each Web App in a given domain will only trust it's own IdP - and only needs to register with it's own IdP.

Security Patterns : Single Sign On across Web Applications and Web Services

The requirement is to have single sign on across different web applications - once the user is  authenticated he should be able to access all the web applications with no further authentication [by him self]. Also, the web applications need to access a set of back-end services with the logged in user's access rights and the back-end services will authorize the user [end-user] based on different claims, like role.

1. User hits the link to the WebApp
2. WebApp finds out user is not authenticated and redirects to the SAML2 IdP.
3. SAML2 Idp checks whether the user has an authenticated session - if not will prompt for credentials, once authenticated there ,user will be redirected back to WebApp with a SAML token, with the set of claims requested by the WebApp
4. Now, the WebApp needs to access a back-end web service with the logged in user's access rights. WebApp passes the SAML token to the PEP based on WS-Trust and authenticates it self [WebApp] to the PEP via trusted-sub-system pattern.
5. PEP will call XACML PDP to authorize the user, based on the claims provided in the SAML token.
6. XACML PDP returns back the decision to the PEP.
7. If it's a 'Permit' - PEP will let the user access the back-end web service.

WSO2 Identity Server : A flexible, extensible and robust platform for Identity Management

WSO2 Identity Server provides a flexible, extensible and robust platform for Identity Management. This blog post looks inside WSO2 Identity Server to identify different plug points available for Authentication, Authorization and Provisioning.

WSO2 Identity Server supports following standards/frameworks for authentication, authorization and provisioning.

1. SOAP based authentication API
2. Authenticators
3. OpenID 2.0 for decentralized Single Sign On
4. SAML2 Web Single Sign On
5. OAuth 2.0
6. Security Token Service based on WS-Trust
7. Role based access control and user management API exposed over SOAP
8. Fine-grained access control with XACML
9. Identity provisioning with SCIM

1. SOAP based authentication API

WSO2 Identity Server can be deployed over an Active Directory, LDAP [ApacheDS, OpenLDAP, Novell eDirectory, Oracle DS.. etc..] or a JDBC based user store. It's a matter of configuration change and once done end users/systems can use the SOAP based authentication API to authenticate against the underlying user store.


















Identity Server by default ships with the embedded ApacheDS - but in a real production setup we would recommend you to go for more production ready LDAP - like OpenLDAP - due to some scalability issues we uncovered in embedded ApacheDS.

The connection to the underlying user store is made through an instance of org.wso2.carbon.user.core.UserStoreManager. Based on your requirement you can either implement the above interface or extend org.wso2.carbon.user.core.common.AbstractUserStoreManager.
















2. Authenticators

By default authentication to the WSO2 Identity Server Management console is via username/password. Although this is what we have by default, we never limit the user to use username/password based authentication. It can be based on certificates or any other propitiatory token types - only thing you need to do is to write your custom authenticator.

There are two type of Authenticators - Front-end Authenticators and Back-end Authenticators. Front-end Authenticators deal with the user inputs and figure out what exactly it needs to have to authenticate a user. For example, WebSEAL authenticator reads basic auth header and iv-user header from the HTTP request and calls it Back-end counter-part to do the actual validation.

Back-end Authenticator exposes it's functionality out side via a SOAP based service and it can internally get connected to a UserStoreManager.

Management console also can have multiple Authenticators configured with it. Based on the applicability and the priority one Authenticator will be picked during the run-time.




















3. OpenID 2.0 for decentralized Single Sign On

WSO2 Identity Server supports following OpenID specifications.
  • OpenID Authentication 1.1
  • OpenID Authentication 2.0
  • OpenID Attribute eXchange
  • OpenID Simple Registration
  • OpenID Provider Authentication Policy Extension
OpenID support is built on top of OpenID4Java - and integrated with the underlying user store seamlessly. Once you deploy WSO2 Identity Server over any existing user store, all the users in the user store will get an OpenID automatically.

If you want to use one user store for OpenID authentication and another for the Identity Server management, that is also possible from the Identity Server 4.0.0 on wards.

 WSO2 Identity Server supports both dumb and smart modes and if you would like you can disable the dumb mode. Disabling dumb mode is needed to reduce the load on OpenID Provider and to force relying parties to use smart mode. Identity Server uses JCache based Infiinispan cache to replicate Associations among different nodes in a cluster.

4. SAML2 Web Single Sign On

WSO2 Identity Server supports SAML2 Web Single Sign On.

OpenID and SAML2 are both based on the same concept of federated identity. Following are some of the difference between them.
  • SAML2 supports single sign-out - but OpenID does not.
  •  SAML2 service providers are coupled with the SAML2 Identity Providers, but OpenID relying parties are not coupled with OpenID Providers.
  • OpenID has a discovery protocol which dynamically discovers the corresponding OpenID Provider, once an OpenID is given.
  • With SAML2, the user is coupled to the SAML2 IdP - your SAML2 identifier is only valid for the SAML2 IdP who issued it. But with OpenID, you own your identifier and you can map it to any OpenID Provider you wish.
  • SAML2 has different bindings while the only binding OpenID has is HTTP 






















5. OAuth 2.0

WSO2 Identity Server supports OAuth 2.0 Core draft 27. We believe there will not any drastic changes between draft v27 and the final version of the specification and keeping an eye on where it's heading to.

Identity Server uses Apache Amber as the underlying OAuth 2.0 implementation.
  • Supports all four grant types listed in the specification, namely Authorization Code grant, Implicit grant, Resource Owner Password grant and Client Credentials grant.
  •  Supports Refreshing access tokens with Refresh tokens
  •  Supports the "Bearer" token profile.
  • Support for distributed token caching using WSO2 Carbon Caching Framework.
  • Support for different methods of securing access tokens before persisting. An extension point is also available for implementing the custom token securing methods.
  •  Extensible callback mechanism to link the authorization server with the resource server.
  •  Supports a range of different relational databases to serve as the token store.
6. Security Token Service based on WS-Trust

WSO2 Identity Server supports Security Token Service based WS-Trust 1.3/14. This is based Apache Rampart.





















STS is seamlessly integrated with the underlying user store and to issue tokens users can be authenticated against it.

User attributes are by default fetched from the underlying user store - but provides extensions points where users can write their own attribute callback handlers. Once those callback handlers are registered with the STS - attributes can be fetched from any user store out side the default underlying user store.

STS can be secured with any of the following security scenarios.
  • UsernameToken
  • Signature
  • Kerberos
  • WS-Trust [Here the STS can act as a Resource STS]
7. Role based access control and user management API exposed over SOAP

WSO2 Identity Server can be deployed over an Active Directory, LDAP [ApacheDS, OpenLDAP, Novell eDirectory, Oracle DS.. etc..] or a JDBC based user store. It's a matter of configuration change and once done end users/systems can use the SOAP based API to manage users [add/remove/modify] and check user authorizations against the underlying user store.
















8. Fine-grained access control with XACML

WSO2 Identity Server supports XACML 2.0 and 3.0. All the policies will be stored in XACML 3.0 but yet capable of evaluating requests either from 2.0 and 3.0.

XACML PDP is exposed via following three interfaces.
  • SOAP based API
  • Thrift based API
  • WS-XACML
Identity Server can act as both a XACML PDP and a XACML PAP. These components are decoupled from each other.

By default all XACML policies are stored inside the Registry - but the users can have their own policy store, by extending PolicyStore API.
















9. Identity provisioning with SCIM

The SCIM support in WSO2 Identity Server is based on WSO2 Charon - and open source Java implementation of SCIM 1.0 released under Apache 2.0 license.

WSO2  Identity Server can act as either a SCIM provide or a consumer. Based on a configuration WSO2 IS can provision users to other systems that do have SCIM support.

OAuth 2.0 Playground with WSO2 Identity Server

WSO2 Identity Server adds OAuth 2.0 support from it's very next release. Hopefully by the end of this August. OAuth Core specification supports four grant types.

1. Authorization Code Grant (authorization_code)
2. Implicit Grant
3. Resource Owner Password Credentials Grant (password)
4. Client Credentials Grant (client_credentials)

First you need to setup the sample web app. You can download it from here and host it in Tomcat. I assume it runs at http://localhost:8080/playground. If the Identity Server is not running on 9443 - then you need to edit the web.xml of the web app appropriately.

Then you need to download the WSO2 Identity Server 4.0.0 server from here.

1. Start the server
2. Login with admin/admin
3. Main/Manage/OAuth/Register New Application




4. Select OAuth 2.0
5. Give an Application Name and any Callback Url. For the sample to work, it should be http://localhost:8080/playground/oauth2client



6. Once you click on "Add" you will be taken to the OAuth Management page
7. Click on the application you just created.



8. Copy the values of Client Id, Client Secret, Access Token Url and Authorie Url -- we need these values later during different stages in the web app.



That's it. We are done. Now go to the web app... http://localhost:8080/playground.

Authorization Grant Type : Select one of the four as per the OAuth spec.
Client Id : Client Id from the above image.
Client Secret : Client Secret from the above image.
Resource Owner User Name : Any valid user name from WSO2 IS.
Resource Owner Password : Password correponding to "Resource Owner User Name".
Scope : By default can be anything. No validation. You can override the functionality if needed.
Authorize Endpoint : Authorize Url from the above image.
Access Token Endpoint : Access Token Url from the above image.


Click on import photos... Then you can execute the OAuth flow by selecting the Grant Type you want.









You can download the complete code of sample web application from here.

From the root level type "mvn clean install" to build it.

Testing WSO2 Identity Server OAuth 2.0 support with Curl

WSO2 Identity Server adds OAuth 2.0 support from it's very next release. Hopefully by the end of this August. OAuth Core specification supports four grant types.

1. Authorization Code Grant (authorization_code)
2. Implicit Grant
3. Resource Owner Password Credentials Grant (password)
4. Client Credentials Grant (client_credentials)

In this blog post we only talk about last two grant types - since those can be directly executed via curl.

First you need to download the WSO2 Identity Server 4.0.0 server from here.

1. Start the server
2. Login with admin/admin
3. Main/Manage/OAuth/Register New Application













4. Select OAuth 2.0
5. Give an Application Name and any Callback Url [need not to be real for this case]


















6. Once you click on "Add" you will be taken to the OAuth Management page
7. Click on the application you just created.













8. Copy the values of Client Id and Client Secret -- we need these values later.






















Now lets see how we get an access token from Identity Server via curl.

This is how it works under Resource Owner Password Credentials grant type.

This is useful when the end user or the resource owner trusts the application. I will not talk about the advantages and disadvantages of this grant type here - will have another blog post on that. Anyway this is a grant type you should use with extra care.

$ curl --user Client_Id:Client_Secret  -k -d "grant_type=password&username=admin&password=admin" -H "Content-Type:application/x-www-form-urlencoded"  https://localhost:9443/oauth2/token

You need to replace Client_Id:Client_Secret with your values...

The response would be something like...

{"token_type":"bearer",
"expires_in":3600,
"refresh_token":"d78e445a78c9bdce17f349068495ebe",
"access_token":"3a1d3e2983fafc73eec3f894cb6eb4"}

Now you can use this access_token to access the protected resource.

Let's how to execute curl to get an access_token with Client Credentials Grant type. Here the client becomes the resource owner. Almost similar to 2-legged OAuth we talked under OAuth 1.0.

curl --user Client_Id:Client_Secret  -k -d "grant_type=client_credentials&username=admin&password=admin" -H "Content-Type:application/x-www-form-urlencoded"  https://localhost:9443/oauth2/token

You need to replace Client_Id:Client_Secret with your values...

The response would be.

{"token_type":"bearer",
"expires_in":3600,
"access_token":"9cdd18286e27dd768b74577276f217be"}