Showing posts with label api-security. Show all posts
Showing posts with label api-security. Show all posts

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. 

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. 

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.

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.