Saturday, October 25, 2014

A Brief History of OpenID Connect

OpenID, which followed in the footsteps of SAML in 2005, revolutionized web authentication. Brad Fitzpatrick, the founder of LiveJournal, initiated it. The basic principle behind both OpenID and SAML is the same. Both can be used to facilitate web single sign on and cross-domain identity federation. OpenID is more community friendly, user centric, and decentralized. Yahoo added OpenID support in mid-January 2008, MySpace announced its support for OpenID in and in late July of that same year,, and Google joined the party in late October. By December 2009, there were more than 1 billion OpenID enabled accounts. It was a huge success as a web single sign on.

OpenID and OAuth 1.0 address two different concerns. OpenID is about authentication, while OAuth 1.0 is about delegated authorization. As both of these standards were gaining popularity in their respective domains, there was interest in combining them so that one can authenticate a user and also get a token to access their resources on their behalf in a single step. The Google Step 2 project is the first serious effort in this direction. It introduced an OpenID extension for OAuth, which basically takes Oauth-related parameters in the OpenID request/response itself. The same people who initiated the Google Step 2 project later brought it into the OpenID foundation.

The Google Step 2 OpenID extension for OAuth specification is available at: http://step2.googlecode.com/svn/spec/openid_oauth_extension/latest/openid_oauth_extension.html.

OpenID has gone through two generations to date. OpenID 1.0/1.1/2.0 is the first generation, while OpenID extension for OAuth is the second. OpenID Connect is the third generation of OpenID.

Yahoo, Google, and many other OpenID Providers will discontinue their support for OpenID 2.0 by mid-2015, and they will migrate into OpenID Connect. 

Unlike OpenID extension for OAuth, OpenID Connect was built on top of OAuth. It simply introduces an identity layer on top of OAuth 2.0. This identity layer is abstracted into an ID token. An OAuth Authorization Server that supports OpenID Connect can return an ID token along with the access token itself.

OpenID Connect vs. OAuth 2.0: http://blog.facilelogin.com/2013/11/oauth-20-vs-openid-connect.html

OpenID Connect was ratified as a standard by its membership on February 26, 2014. OpenID Connect provides a lightweight framework for identity interactions in a RESTful manner. This was developed under the OpenID foundation, having its roots in OpenID, but OAuth 2.0 affected it tremendously.

The announcement by the OpenID Foundation regarding the launch of the OpenID Connect standard is available at: http://openid.net/2014/02/26/the-openid-foundation-launches-the-openid-connect-standard/

More details and the applications of the OpenID Connect are covered in my book Advanced API Security.

Friday, October 10, 2014

Dynamic Client Registration Profile

According to the OAuth 2.0 core specification, all OAuth clients must be registered with the OAuth authorization server and obtain a client identifier before any interactions. The aim of the Dynamic Client Registration OAuth 2.0 profile is to expose an endpoint for client registration in a standard manner to facilitate on-the-fly registrations.

The Dynamic Client Registration OAuth 2.0 profile is available at https://datatracker.ietf.org/doc/draft-ietf-oauth-dyn-reg

The dynamic-registration endpoint exposed by the authorization server can be secured or not. If it’s secured, it can be secured with OAuth, HTTP Basic Authentication, Mutual TLS, or any other security protocol as desired by the authorization server. The Dynamic Client Registration profile doesn’t enforce any authentication protocols over the registration endpoint, but it must be secured with TLS. If the authorization server decides that it should allow the endpoint to be public and let anyone be registered, it can do so.

To register a client, it must pass all its metadata to the registration endpoint. Following lists out only a subset of the request attributes. In addition to these, the profile also has the provision to introduce your custom attributes as well.

POST /register HTTP/1.1 
Content-Type: application/json 
Accept: application/json 
Host: authz.server.com 


   "redirect_uris":["https://client.org/callback","https://client.org/callback2"],  
   "token_endpoint_auth_method":"client_secret_basic", 
   "grant_types": ["authorization_code" , "implicit"], 
   "response_types": ["code" , "token"], 


Let’s have a look at the definition of each parameter.

redirect_uris: An array of URIs under the control of the client. The user is redirected to one of these redirect_uris after the authorization grant.

token_endpoint_auth_method: The supported authentication scheme when talking to the token endpoint. If the value is client_secret_basic, the client sends its client ID and the client secret in the HTTP Basic Authorization header. If it’s client_secret_post, the client ID and the client secret are in the HTTP POST body. If the value is none, the client doesn’t want to authenticate, which means it’s a public client (as in the case of the OAuth Implicit grant type).

grant_types: An array of grant types supported by the client.

response_types: An array of expected response types from the authorization server.

Based on the policies of the authorization server, it can decide whether it should proceed with the registration. Even if it decides to go ahead with the registration, the authorization server need not accept all the suggested parameters from the client. For example, the client may suggest using both authorization_code and implicit as grant types, but the authorization server can decide what to allow. The same is true for the token_endpoint_auth_method: the authorization server can decide what to support.

The following is a sample response from the authorization server:

HTTP/1.1 200 OK 
Content-Type: application/json 
Cache-Control: no-store 
Pragma: no-cache 


"client_id":"iuyiSgfgfhffgfh", 
"client_secret": "hkjhkiiu89hknhkjhuyjhk", 
"client_id_issued_at":2343276600, 
 "client_secret_expires_at":2503286900, 
 "redirect_uris":["https://client.org/callback", "https://client.org/callback2"], 
 "grant_types": "authorization_code", 
 "token_endpoint_auth_method": "client_secret_basic"


Let’s have a look at the definition of each parameter.

client_id: A generated unique identifier for the client.

client_secret: The generated client secret corresponding to the client_id. This is optional. For the Implicit grant type, client_secret isn’t required.

client_id_issued_at: The number of seconds since January 1, 1970.

client_secret_expires_at: The number of seconds since January 1, 1970.

redirect_uris: Accepted redirect_uris.

token_endpoint_auth_method: The accepted authentication method for the token endpoint.

The Dynamic Client Registration OAuth 2.0 profile is extremely useful in mobile applications. Mobile client applications secured with OAuth have the client ID and the client secret baked into the application. These are the same for all installations for a given application. If a given client secret is compromised, that will affect all installations, and rogue client applications can be developed using the stolen keys. These rogue client applications can generate more traffic on the server and exceed the legitimate throttling limit, hence causing a denial of service attack. With dynamic client registration, you need not set the same client ID and client secret for all installations. During the installation process, the application can talk to the authorization server’s registration endpoint and generate a client ID and a client secret per installation.

More details and the applications of the OAuth 2.0 Dynamic Client Registrayion Profile are covered in my book Advanced API Security

Thursday, October 9, 2014

Revamping WSO2 API Manager Key Management Architecture around Open Standards

WSO2 API Manager is a complete solution for designing and publishing APIs, creating and managing a developer community, and for scalably routing API traffic. It leverages proven, production-ready integration, security, and governance components from the WSO2 Enterprise Service Bus, WSO2 Identity Server, and WSO2 Governance Registry. In addition, it leverages the WSO2 Business Activity Monitor for Big Data analytics, giving you instant insight into APIs behavior.

One of the limitation we had in API Manager so far is its tight integration with the WSO2 Identity Server. WSO2 Identity Server acts as the key manager, which issues and validates OAuth tokens.

With the revamped architecture (still under discussion) we plan to make all integration points with the key manager, extensible - so you can bring in your own OAuth authorizations server. And also - we will ship the product with standard extension points. These extension points are built around corresponding OAuth 2.0 profiles. In case, your authorization server deviates from the standard, you need to implement the KeyManager interface and plug in your own implementation.

Screen Shot 2014-08-27 at 12.08.49 AM.png 

API Publisher 

API Developer first logs-in to the API Publisher and creates an API with all the related metadata and publishes it to the API Store and the API Gateway.

API Publisher will also publish API metadata into the external authorization server via OAuth Resource Set Registration endpoint [1].

Sample Request:


"name": "Photo Album", 
"icon_uri": "http://www.example.com/icons/flower.png", 
"scopes": [ "http://photoz.example.com/dev/scopes/view", 
                  "http://photoz.example.com/dev/scopes/all" ], 
"type": "http://www.example.com/rsets/photoalbum" 


name REQUIRED. A human-readable string describing a set of one or more resources. This name MAY be used by the authorization server in its resource owner user interface for the resource owner.

icon_uri OPTIONAL. A URI for a graphic icon representing the resource set. The referenced icon MAY be used by the authorization server in its resource owner user interface for the resource owner.

scopes REQUIRED. An array providing the URI references of scope descriptions that are available for this resource set.

type OPTIONAL. A string uniquely identifying the semantics of the resource set. For example, if the resource set consists of a single resource that is an identity claim that leverages standardized claim semantics for "verified email address", the value of this property could be an identifying URI for this claim.

Sample Response:

HTTP/1.1 201 
Created Content-Type: application/json 
ETag: (matches "_rev" property in returned object) ... 

{ "status": "created", "_id": (id of created resource set), 
  "_rev": (ETag of created resource set) 


The objective of publishing the resources to the authorization server is to make it aware of the available resources and the scopes associated with them. An identity administrator can build the relationship between these scopes and the enterprise roles. Basically you can associate scopes with enterprise roles.

API Store 

Application Developer logs-in to the API Store and discovers the APIs he/she wants for his application and subscribes to those - and finally creates an application. Each application is uniquely identified by its client id. There are two ways to associate a client id with an application created in API Store.

1. Application developer brings in the client id.

Application developer creates a client id out-of-band with the authorization server, and associates the client id with the application he just created in the API Store. In this case, Dynamic Client Registration endpoint of the Authorization Serve is not used (No step 3 & 4).

2. API Store calls Dynamic Client Registration endpoint of the external Authorization Server.

Once the application is created by the application developer (by grouping a set of APIs) - API Store will call the Dynamic Client Registration endpoint of the authorization server.

Sample Request (Step 3):

POST /register HTTP/1.1 
Content-Type: application/json 
Accept: application/json 
Host: authz.server.com 


"client_name": "My Application”, 
"redirect_uris":[" https://client.org/callback","https://client.org/callback2 "], "token_endpoint_auth_method":"client_secret_basic", 
"grant_types": ["authorization_code" , "implicit"], 
"response_types": ["code" , "token"], 
"scope": ["sc1" , "sc2"], 


client_name: Human-readable name of the client to be presented to the user during authorization. If omitted, the authorization server MAY display the raw "client_id" value to the user instead. It is RECOMMENDED that clients always send this field.

client_uri: URL of a web page providing information about the client. If present, the server SHOULD display this URL to the end user in a clickable fashion. It is RECOMMENDED that clients always send this field.

 logo_uri: URL that references a logo for the client. If present, the server SHOULD display this image to the end user during approval. The value of this field MUST point to a valid image file.

scope :Space separated list of scope values that the client can use when requesting access tokens. The semantics of values in this list is service specific. If omitted, an authorization server MAY register a client with a default set of scopes.

grant_types: Array of OAuth 2.0 grant types that the client may use.

response_types: Array of the OAuth 2.0 response types that the client may use.

token_endpoint_auth_method: The requested authentication method for the token endpoint.

redirect_uris: Array of redirection URI values for use in redirect-based flows such as the authorization code and implicit flows.

Sample Response (Step 4):

HTTP/1.1 200 OK 
Content-Type: application/json 
Cache-Control: no-store 
Pragma: no-cache 


"client_id":"iuyiSgfgfhffgfh", 
"client_secret": "hkjhkiiu89hknhkjhuyjhk", 
"client_id_issued_at":2343276600, 
"client_secret_expires_at":2503286900, 
"redirect_uris":[" https://client.org/callback ", " https://client.org/callback2 "], 
"grant_types": "authorization_code", 
"token_endpoint_auth_method": "client_secret_basic"

OAuth Client Application 

This is outside the scope of the API Manager. The client application can talk to the external authorization server via any of the grant types it supports and obtain an access token [3]. The scope parameter is optional in all the token requests - when omitted by the client, the authorization server can associate a default scope with the access token. If no scopes used at all - then the API Gateway can do an authorization check based on other parameters associated with OAuth client, end user, resource and action.

If the client sends a set of scopes with the OAuth grant request, then these scopes will be meaningful to the authorization server only if we have published API metadata into the external authorization server via the OAuth Resource Set Registration endpoint - from the API Publisher. Based on the user's role and the scopes associated with role, authorization server can issue the access token, only for a subset of the scopes request by the OAuth client.

Client Credentials Grant Type Sample Request:

POST /token HTTP/1.1 
Host: server.example.com Authorization: Basic Base64Encode(Client ID:Client Secret) Content-Type: application/x-www-form-urlencoded 

grant_type=client_credentials 

Sample Response:

HTTP/1.1 200 OK 
Content-Type: application/json;charset=UTF-8 
Cache-Control: no-store Pragma: no-cache 


"access_token":"2YotnFZFEjr1zCsicMWpAA", 
"token_type":"example", 
"expires_in":3600, 
"example_parameter":"example_value" 


Resource Owner Password Grant Type Sample Request:

POST /token HTTP/1.1 Host: server.example.com 
Authorization: Basic Base64Encode(Client ID:Client Secret) 
Content-Type: application/x-www-form-urlencoded 

grant_type=password&username=johndoe&password=A3ddj3w

Sample Response:

HTTP/1.1 200 OK 
Content-Type: application/json;charset=UTF-8 
Cache-Control: no-store Pragma: no-cache 


"access_token":"2YotnFZFEjr1zCsicMWpAA", 
"token_type":"example", "expires_in":3600, 
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", 
"example_parameter":"example_value" 

API Gateway 

The API Gateway will intercept all the messages flowing between the OAuth client application and the API - and extract out the access token comes in the HTTP Authorization header. Once the access token is extracted out, API Gateway will call the Token Introspection endpoint[4] of the authorization server.

Sample Request:

POST /introspect HTTP/1.1
Host: authserver.example.com
Content-type: application/x-www-form-urlencoded
Accept: application/json
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

token=X3241Affw.4233-99JXJ

Sample Response:


"active": true, 
"client_id":"s6BhdRkqt3", 
"scope": "read write dolphin", 
"sub": "2309fj32kl", 
"user_id": "jdoe", 
"aud": "https://example.org/protected-resource/*", 
"iss": "https://authserver.example.com/" 


active REQUIRED. Boolean indicator of whether or not the presented token is currently active.

exp OPTIONAL. Integer timestamp, measured in the number of seconds since January 1 1970 UTC, indicating when this token will expire.

iat OPTIONAL. Integer timestamp, measured in the number of seconds since January 1 1970 UTC, indicating when this token was originally issued.

scope OPTIONAL. A space-separated list of strings representing the scopes associated with this token.

client_id REQUIRED. Client Identifier for the OAuth Client that requested this token.

sub OPTIONAL. Machine-readable identifier local to the AS of the Resource Owner who authorized this token.

user_id REQUIRED. Human-readable identifier for the user who authorized this token.

aud OPTIONAL. Service-specific string identifier or list of string identifiers representing the intended audience for this token.

iss OPTIONAL. String representing the issuer of this token.

token_type OPTIONAL. Type of the token as defined in OAuth 2.0

Once the API Gateway gets the token introspection response from the authorization server, it will check whether the client application (client id) has subscribed to the corresponding API and then also will validate the scope. API Gateway knows the required scopes for the API and the introspection response returns back the scopes associated with access token.

If everything is fine, API Gateway will generate a JWT and send it  to the downstream API. The generated JWT can optionally include user attributes as well. In that case API Gateway will  talk to the UserInfo endpoint of the authorization server.

Also - the API Gateway can simply pass-thru the access token as well - without validating the access token and its associated scopes. In that case API Gateway will only do throttling and monitoring.

Secured Endpoints

In this proposed revamped architecture, WSO2 API Manager has to talk to following endpoints exposed by the key manager.
  • Resource set registration
  • Dynamic client registration endpoint
  • Introspection endpoint
  • UserInfo endpoint
For the first three endpoints, the API Manager will just act as a trusted system. The corresponding KeyManager implementation should know how to authenticate to those endpoints. The OpenID Connect UserInfo endpoint will be invoked with the user provided access token, in run-time. This will work only if the corresponding access token has the privileges to read user's profile from the authorization server.

References

[1]: http://tools.ietf.org/html/draft-hardjono-oauth-resource-reg-02
[2]: http://tools.ietf.org/html/draft-ietf-oauth-dyn-reg-19
[3]: http://tools.ietf.org/html/rfc6749
[4]: http://tools.ietf.org/html/draft-richer-oauth-introspection-06

Wednesday, October 8, 2014

OAuth 2.0 Chain Grant Type Profile


Once the audience restriction is enforced on OAuth tokens, they can only be used against the intended audience. You can access an API with an access token that has an audience restriction corresponding to that API. If this API wants to talk to another protected API to form the response to the client, the first API must authenticate to the second API. When it does so, the first API can’t just pass the access token it received initially from the client. That will fail the audience-restriction validation at the second API.

The audience (aud) parameter is defined in the OAuth 2.0: Audience Information Internet draft available at http://tools.ietf.org/html/draft-tschofenig-oauth-audience-00. This is a new parameter introduced into the OAuth token-request flow and is independent of the token type. 

The Chain Grant Type OAuth 2.0 profile defines a standard way to address this concern. As shown in the above figure, according to the OAuth Chain Grant Type profile, the API hosted in the first resource server must talk to the authorization server and exchange the OAuth access token it received from the client for a new one that can be used to talk to the other API hosted in the second resource server.

The Chain Grant Type for OAuth 2.0 profile is available at https://datatracker.ietf.org/doc/draft-hunt-oauth-chain. 

The chain grant type request must be generated from the first resource server to the authorization server. The value of the grant type must be set to http://oauth.net/grant_type/chain and should include the OAuth access token received from the client. The scope parameter should express the required scopes for the second resource in space-delimited strings. Ideally, the scope should be the same as or a subset of the scopes associated with original access token. If there is any difference, then the authorization server can decide whether to issue an access token. This decision can be based on an out-of-band agreement with the resource owner:

POST /token HTTP/1.1 
Host: authz.server.net 
Content-Type: application/x-www-form-urlencoded 

grant_type= http://oauth.net/grant_type/chain 
oauth_token=dsddDLJkuiiuieqjhk238khjh 
scope=read 

This returns the following JSON response. The response includes an access token with a limited lifetime, but it should not have a refresh token. To get a new access token, the first resource server once again must present the original access token:

HTTP/1.1 200 OK 
Content-Type: application/json;charset=UTF-8 
Cache-Control: no-store 
Pragma: no-cache 

{ "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"Bearer", "expires_in":1800, } 

The first resource server can use the access token from this response to talk to the second resource server. Then the second resource server talks to the authorization server to validate the access token.

More details and the applications of the OAuth 2.0 Chain Grant Type Profile are covered in my book Advanced API Security

Tuesday, October 7, 2014

OAuth 2.0 Token Introspection Profile

OAuth 2.0 doesn’t define a standard API for communication between the resource server and the authorization server. As a result, vendor-specific, proprietary APIs have crept in to couple the resource server to the authorization server. The Token Introspection profile for OAuth 2.0 fills this gap by proposing a standard API to be exposed by the authorization server, allowing the resource server to talk to it and retrieve token metadata.

OAuth 2.0 Token Introspection Internet draft is available at https://datatracker.ietf.org/doc/draft-richer-oauth-introspection/

A token-introspection request can be generated by any party in possession of the access token. The introspection endpoint can be secured with HTTP Basic Authentication:

POST /introspection HTTP/1.1 
Accept: application/x-www-form-urlencoded 
Host: authz.server.com 
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3 

token=X3241Affw.4233-99JXJ&token_type_hint=access_token&resource_id=http://my-resource 

Let’s have a look at the definition of each parameter.
  • token: The value of the access-token 
  • token_type_hint: The type of the token (either the access_token or the refresh_token) 
  • resource_id: An identifier that represents the corresponding resource for introspection
This request returns the following JSON response:

HTTP/1.1 200 OK 
Content-Type: application/json Cache-Control: no-store 


  "active": true, 
  "client_id":"s6BhdRkqt3", 
  "scope": "read write dolphin", 
  "sub": "2309fj32kl", 
  "aud": " http://my-resource/* 
 } 

Let’s have a look at the definition of each parameter.
  • active: Indicates whether the token is active. To be active, the token should not be expired or revoked. The authorization server can define its own criteria for how to define active. 
  • client_id: The identifier of the client to which the token was issued. 
  • scope: Approved scopes associated with the token. 
  • sub: The subject identifier of the user who approved the authorization grant. 
  • aud: The allowed audience for the token. 
The audience (aud) parameter is defined in the OAuth 2.0: Audience Information Internet draft available at http://tools.ietf.org/html/draft-tschofenig-oauth-audience-00. This is a new parameter introduced into the OAuth token-request flow and is independent of the token type. 

While validating the response from the introspection endpoint, the resource server should first check whether the value of active is set to true. Then it should check whether the value of aud in the response matches the aud URI associated with the resource server or the resource. Finally, it can validate the scope. The required scope to access the resource should be a subset of the scope values returned in the introspection response. If the resource server wants to do further access control based on the client or the resource owner, it can do so with respect to the values of sub and client_id.

More details and the applications of the OAuth 2.0 Token Introspection Profile are covered in my book Advanced API Security.

Monday, October 6, 2014

Single Sign-On with the Delegated Access Control Pattern

 Suppose a medium-scale enterprise has a limited number of RESTful APIs. Company employees are allowed to access these APIs via web applications while they’re behind the company firewall. All user data is stored in a Microsoft Active Directory, and all the web applications are connected to a Security Assertion Markup Language (SAML) 2.0 identity provider to authenticate users. The web applications need to access back-end APIs on behalf of the logged-in user.

The catch here is this last statement: “The web applications need to access back-end APIs on behalf of the logged-in user.” This suggests the need for an access-delegation protocol: OAuth. However, users don’t present their credentials directly to the web application—they authenticate through a SAML 2.0 identity provider.

In this case, you need to find a way to exchange the SAML token received in the SAML 2.0 Web SSO protocol for an OAuth access token, which is defined in the SAML grant type for the OAuth 2.0 specification. Once the web application receives the SAML token, as shown in step 3 of the above figure, it has to exchange it with an access token by talking to the OAuth authorization server.

The authorization server must trust the SAML 2.0 identity provider. Once the web application gets the access token, it can use it to access back-end APIs. The SAML grant type for OAuth doesn’t provide a refresh token. The lifetime of the access token issued by the OAuth authorization must match the lifetime of the SAML token used in the authorization grant.

After the user logs in to the web application with a valid SAML token, the web app creates a session for the user from there onward, and it doesn’t worry about the lifetime of the SAML token. This can lead to some issues. Say the SAML token expires, but the user still has a valid browser session in the web application. Because the SAML token has expired, you can expect that the corresponding OAuth access token obtained at the time of user login has expired as well. Now, if the web application tries to access a back-end API, the request will be rejected because the access token is expired. In such a scenario, the web application has to redirect the user back to the SAML 2.0 identity provider, get a new SAML token, and exchange that token for a new access token. If the session at the SAML 2.0 identity provider is still live, then this redirection can be made transparent to the end user.

This is one of the ten API security patterns covered in my book Advanced API Security. You can find more details about this from the book.