As part of our migration from SOASoft to our new API Manager we are also changing how client applications gain access to protected resources. SOASoft uses a home grown system called APIKey. Our new API Manager takes advantage of the OAuth 2.0 industry standard. The two authorization schemes share some similarities.
The APIKey infrastructure was created by OIT a number of years ago using the best practice ideas at the time. In this authorization scheme a set of credentials (id, shared secret) is exchanged for a nonce from the authorization server. Once a nonce is obtained it is combined with the credentials to form an authorization request.
There are two types of APIKeys:
Permanent (Trusted Partner) - Organizations can request permanent APIKey credentials (id, shared secret) be assigned. This APIKey can use Actors if it has been granted elevated rights.
Temporary - A temporary set of APIKey credentials (id, shared seret) can be requested by using a netid and password. This APIKey cannot be assigned elevated rights and cannot use Actors.
By default all access to APIs with APIKeys are bound to the identity of the owner of the APIKey - the Trusted Partner for a permanent APIKey or the netid for a temporary APIKey. The identity of the owner is passed to all APIs for processing. APIs then use that identity to determine what functions and data the client application was allowed to access.
BYU's APIKey implementation included the concept of an Actor. In short a client application with appropriate privileges could specify the netid of the person they wished to act on behalf of as part of the API Request. The API Key infrastructure would validate that the client application had sufficient rights to specify an Actor and pass the Actor identity instead of the owner of the APIKey to the APIs for processing, thus impersonating the Actor.
The APIKey process is as follows:
(Optional) If a Temporary key is to be used the client sends a HTTP POST request to the
https://ws.byu.edu/authentication/services/rest/v1/ws/sessionendpoint. The endpoint returns a set of temporary APIKey credentials.
For each API call the client first obtains a nonce by sending a HTTP POST to
https://ws.byu.edu/authentication/services/rest/v1/hmac/nonce/and including the APIKey id (temporary or permanent). If the client is using an Actor the netid of the actor is included in the URL used to gain the nonce.
The client computes a WSSession key from the nonce, APIKey id, and shared secret and includes this in the
Authorizationheader included with the API request.
- The request is validated by the Resource Server (via the Autorization Server) and the identity of the requester (owner or Actor) is passed to the resource server via HTTP headers.
OAuth is a standard for authorization of API requests. All applications using OAuth must be registered with the API Manager and obtain a set of client credentials (client-id and client-secret). Once registered a client application subscribes to the APIs it wishes to use. A variety of methods (called grant types) can be used at runtime to obtain authorization to access protected resources.
OAuth Client Credentials Grant Type
The client credentials grant type is one of the simplest of the OAuth 2.0 grant types. This grant type only identifies the client application and is not concerned with the identity of the user of the client application. Thus it is conceptually the same as the APIKey.
Client_id and Client_Secret
OAuth 2.0 assigns each client application a client_id and a client_secret. The client_id is an identifier of the client and is used in a number of contexts. The client_id is considered public and does not need to be secured. The client_secret is to be kept confidential (much like a password). If the client_secret is compromised the client_id and client_secret must be invalidated as a set and a new set of credentials issued.
Actors in OAuth 2.0
There is no equivalent of BYU's APIKey Actor concept within OAuth 2.0. Most OAuth 2.0 grant types include the identity of the user of the client application as well as the identity of the client application. We have added Actor support, including the check for rights to use an Actor, to legacy APIs in order to allow them to be used with our new API Manager. This is for support of legacy APIs only. Access to new APIs should use a different grant type to include user identity information in the request.
The OAuth Client Credentials Grant Type process is as follows:
The client application is registered with the API Manager (instructions).
The client application subscribes to the APIs it wishes to use (instructions).
If the client application needs to use Actors with legacy APIs it can be granted elevated rights that are equivalent to those it had using APIKeys (instructions).
For each API call the client application includes an Authorization HTTP header with the word "Bearer" followed by the access_token as the value. Actors are specified by adding an
Acting-ForHTTP header to the request.
If the request returns an HTTP 401 status code the access_token has expired. The client calls the token_endpoint just as in step 4 to obtain a new access_token and repeat the request. Access_tokens are generally good for an hour. Be sure to check the message that accompanies the 401 status code - the code could be returned by the API as well as the API Manager.
Revoke the access_token when finished using it.(instructions)
Sample code for all of the OAuth 2.0 grant types can be found here.
Converting from APIKey to Client Credentials
The process of converting from APIKey to Client Credentials consists of:
Register the client application with the API Manager.
Subscribe to the APIs the client application needs to use.
Have OIT transfer any elevated rights from your old APIKey to the new client_id.
Add code to obtain an access_token using the assigned client_id and client_secret.
Attach an Authorization HTTP header with the access_token to all API requests.
Check for a 401 HTTP response code. If the message indicates the token has expired obtain a new access_token and repeat the request.
Revoke the access_token when finished.