IBM Support

Grant type scenario for client credentials

White Papers


Abstract

Part 5 of multi-part series describes WebSphere DataPower Appliance support for the OAuth 2.0 client credential grant type. It covers configuration of both the authorization server and the enforcement point.

Content

Introduction

The client credentials grant is one of the four grant types defined in the OAuth 2.0 Specification Framework (Section 4.4). Given grant type differs from the other grant types in that the client itself is the resource owner. The client application can obtain an access token by presenting just its own credentials.  With given grant type, the client avoids having its credential being exposed in every resource request on the wire.

For general information about OAuth, see Part 1 of the series, Introducing OAuth 2.0 support in DataPower, or the IETF OAuth 2.0 Authorization Framework. In particular, Section 4.4 of the OAuth 2.0 Specification covers the client credential grant type discussed here. Figure 1 illustrates the request flow. It's identical to Figure 1 in Part 4 series. In Part 4, the client did not own the resource; it merely knew the resource owners credentials. In the article, the client is the resource owner. They look the same diagrammatically. However, the request to the authorization server is different.

Figure 1. Client credentials flowClient credentials                     flow

The flow illustrated in Figure 1 provides a high-level overview of the client credentials flow:

  1. The client application presents its client credentials (client identifier and client secret) to the authorization server (DataPower is the authorization server endpoint), requesting approval to access the protected resource (owned by the client application) on the resource server. The authorization server authenticates the client credential and issues an access token.
  2. The client application presents the access token to the enforcement point (DataPower is the enforcement point for a resource server), requesting access to the protected resource. DataPower validates the access token. If the access token is valid for the requested scope, DataPower sends the request to the resource server and returns the resource to the client application.

Implementing the client credentials grant type

In our scenario, a client application would like to retrieve the account information (protected resource) stored at a remote HTTP server (resource server).

Scenario is implemented as follows:

  1. Register the client application with the DataPower appliance.
  2. Configure the authorization server support within DataPower.
  3. Configure the enforcement point support for a resource server within DataPower.

In Step 1, you create an OAuth client profile named account-application for the client. You also create an OAuth client group referencing the configured OAuth client profile. The OAuth Client Group used by the AAA policy in Step 2 and Step 3 to support the OAuth authorization. It is "registering the client application."

In Step 2, you create an AAA policy that supports OAuth and a Web Token Service that implements an OAuth authorization server. It validates requests for an access token and issue access tokens.

In Step 3, you create an AAA policy that supports OAuth and a Multi-Protocol Gateway service that implements an enforcement point for the resource server. The enforcement point validates the access tokens.

Preparing for DataPower configuration

In order to concentrate on OAuth configuration, some pre-configured DataPower objects are provided for you in the Downloadable resources section of article.

  1. Create a new DataPower application domain for article and switch to it.
  2. Set the default log level of the domain to information.
  3. Article uses the same set of shared secret and SSL keys used by the other articles in series. Download OAuthArticleKeys.zip and unzip it if you haven't already. Upload sharedSecretKey.txt, sslserver-privkey.pem, and sslserver-sscert.pem into the cert: directory of your new application domain.
  4. Article uses a simple XML Firewall for the backend. It is packaged in an archive named AccountLoopback.zip. Download and import file if you haven't already. If XML Firewall is already running in another application domain from a previous exercise, then you can skip this step to avoid a conflict on TCP port 5001.
  5. Download and import Part5BeginState.zip. It contains the following:
    1. An SSL Proxy Profile: sslserver that references the SSL key files from Step 3.
    2. A local file, local:///AAAInfo.xml, used for simple authentication and authorization.
  6. Verify the following:
    1. The SSL Proxy Profile sslserver state is up.
    2. The XML Firewall loopback state is up. (It can be deployed to a different application domain if you deployed it earlier.)
    3. The file local:///AAAInfo.xml exists.

Step 1: Creating a client registration

  1. Create OAuth client profile by navigating to Objects > Crypto Configuration > OAuth Client Profile.
  2. Add a new OAuth client profile. The Main tab is shown in Figure 2.
    Figure 2. OAuth client profileOAuth client profile
     

    Populate these fields:

    1. The Name is "account-application". It becomes the client identifier.
    2. The Supported Authorization Grant Type is "Client Credentials." The grant type is the focus of this article.
    3. The Client Secret is "passw0rd". It is used to authenticate the client with the authorization server. You need to uncheck the Generate Client Secret checkbox to specify the secret. The checkbox disappears once you populate the Client Secret field. To get the checkbox back, remove the content from the Client Secret field.
    4. The Scope is "getAccount". The scope value specified in the access request is checked against values defined here.
    5. The Access Token Lifetime (on the Advanced tab in 6.0) defines the lifetime in seconds of the access token.
    6. The Shared Secret protects tokens used by the OAuth protocol. Click the "+" button next to Shared Secret to create a shared secret object, as shown in Figure 3. The object references the sharedSecretKey.txt file uploaded during the preparation section. It is used to encrypt and decrypt the access token generated by DataPower. The key material is 64 hex digits prefixed by "0x". For information on generating secure secret keys for your own use, see The shared secret key section in Part 4 of the article series or Perfect Passwords.
      Figure 3. Shared secret keyShared secret key
  3. Click Apply for the OAuth Client Profile.
  4. Navigate to Objects > Crypto Configuration > OAuth Client Group. An OAuth Client Group manages the registration of OAuth clients for a single OAuth authorization server endpoint. For exercise, select the client profile you configured. Click Add to enter details for a new group.
  5. Populate the following fields:
    1. Name: registeredClients
    2. Client: Select the account-application and click the Add button.
  6. Click Apply.
    Figure 4. OAuth client groupOAuth client group

    Note: The Add button is important in Step 5. If you only select account-application, but don't add it, you are left with an empty list of clients.

Step 2: Configuring DataPower as the OAuth authorization server

  1. Navigating to Objects > XML Processing > AAA Policy.
  2. Click Add to create an AAA policy.
  3. Set Name to clientcred-aaa.
  4. Select the Identity Extraction tab. Select OAuth as the method and choose the registeredClients OAuth Client Group.
  5. Select the Authentication tab. Select Pass Identity Token to the Authorize Step.
  6. Select the Resource extraction tab. Select Processing Metadata and choose oauth-scope-metadata for processing metadata items.
  7. Select the Authorization tab. Select AAA information file as the method and specify the file as local:///AAAInfo.xml.
  8. Click Apply.

    There are several methods supported by DataPower that perform authorization. Here, we use the AAA information file for its ease of configuration. The AAAInfo.xml in the local directory is based on store:///AAAInfo.xml and was uploaded to the local: directory during the preparation import. The code snippet below shows how an authorization entry was added for account-application. It is both the client and the resource owner.

       <Authorize>   <InputCredential>account-application</InputCredential>   <InputResource>getAccount</InputResource>   <Access>allow</Access> </Authorize>

    The next step is to create a Web Token Service (WTS) from the AAA policy. The WTS wizard was covered in detail in Part 3. For the WTS creation wizard screenshots, see Part 3 article series.

  9. From the left-side navigation panel, select Services > Web Token Service > New Web Token Service.
  10. Name service OAuth-azsvr and click Next.
  11. Enter 5050 for Port and select the imported SSL Proxy Profile named sslserver. Click Add and then Next.
  12. Select the clientcred-aaa AAA policy you created from the drop down menu and click Next.
  13. Click Commit to create the WTS. The WTS wizard generates the processing policy and all actions required for the OAuth token service.

    For given case, a processing policy with two rules is created as shown in Figure 5. After committing the WTS, view the completed service and click the Processing Policy edit button "..." to view the policy with its two rules:

    • One matches */favicon.ico to ignore the favicon request sent by browsers.
    • One matches * that includes the http-convert action and the AAA policy you created.
    Figure 5. Web Token Service – processing policyWeb Token Service – processing policy

Step 3: Configuring DataPower as the enforcement point for a resource server

The authorization server we configured in the previous step returns the access token. The enforcement point service proxy created in the step verifies the token before allowing a request to pass.

  1. Navigating to Objects > XML Processing > AAA Policy. Click Add to create a new AAA policy and name it rssvr-aaa.
  2. Select the Identity Extraction tab. Select OAuth as the method and choose the registeredClients OAuth Client Group.
  3. Select the Authentication tab. Select Pass Identity Token to the Authorize Step.
  4. Select the Resource extraction tab. Check URL sent by client and Processing metadata. Select oauth scope metadata for the dropdown. DataPower performs a comparison of the output from "URL sent by client" against the scope allowed by the access token.
  5. Select the Authorization tab. Select Allow Any authenticated client.
  6. Click Apply.
  7. The enforcement point is implemented with a MPGW. Navigate to the Control Panel, select Multi-Protocol Gateway, and click Add. Enter the following.
    • Service Name: enforcementPoint-rssvr
    • Backend URL: http://127.0.0.1:5001
    • Request Type: Non-XML.
    • Response Type: Pass through
  8. Create the HTTPS Front Side Protocol by clicking "+" next to Front Side Protocol field and selecting HTTPS Front Side Handler. Populate its fields as indicated below.
    • Name: HTTPS-rssvr
    • Port: 5051
    • Check GET method.
    • SSL Proxy: Select sslserver.
    • Click Apply.
  9. Create the processing policy by clicking "+" next to Multi-Protocol Gateway Policy. Populate its fields as indicated below.
    • Policy Name: enforcementPoint
    • Click the New Rule button and change Rule Direction to Client to Server.
    • Double-click the Match action. Create a new match rule called MatchAll. Add a matching rule for all URLs in the Matching Rule tab.
    • Drag an Advanced action after the Match action. Double-click it and select Convert Query Params to XML. Click Next and then Done.
    • Drag an AAA action after the Convert action and double-click it. Select the rssvr-aaa AAA Policy from the dropdown menu.

    The result looks similar to Figure 6.

    Figure 6. MPGW – processing policyMPGW – processing policy
  10. Click Apply Policy and close the window. Then, click Apply for the MPGW.

This completes the configuration for the OAuth client credentials flow. The next section shows you how to request an access token from DataPower and use it to access a protected resource. You have two avenues available to you for testing:

  • The curl command line tool to simulate both the resource owner and the client application. You can download the curl tool.
  • A Node.js application to simulate the client while you and your browser simulate the resource owner. You can download the Node.js application.

The next section explains how to use the curl tool. The Node.js application provides instructions on its homepage.

Sample request and response

In this section, the client first makes a request for an access token. The authorization server (Web Token Service configured in Step 2) receives the request and authenticates the client ID and secret. It returns an access token to the client if the request is valid. Otherwise, an error code is returned. The client then makes a request to the resource server (MPGW service configured in Step 3). The enforcement point receives the request, validates the access token, and returns the resource back to the client if the request is valid. Otherwise, the client access is rejected.

Client requests an access token that uses the client credentials grant type

To request an access token uses client credentials grant, the client must present its client credentials to the authorization server (Web Token Service, listening on port 5050), and add two required parameters in its request:

  • Parameter grant_type with the value set to client_credentials.
  • Parameter scope to indicate the resource of interest.
   curl -k https://<DataPower IP>:5050/token –-user account-application:passw0rd -d "grant_type=client_credentials&scope=/getAccount"

The --user option in the above command places the client credentials in the HTTP Authorization header. They can also be sent in the body of the request as the client_id and client_secret parameters as shown below.

   curl -k https://<DataPower IP>:5050/token -d "grant_type=client_credentials&scope=/getAccount&client_id= account-application&client_secret=passw0rd"

The authorization server verifies the client credentials and returns an access token if the authentication is successful. The response contains the access token, the token type, the token lifetime, and the scope granted in the following format (line breaks added for clarity).

   { "token_type":"bearer",   "access_token":"<Access_Token>",   "expires_in":3600,   "scope":"/getAccount" }

If the authorization server fails to validate the access request, an error code is included in the response. In order to acquire more detailed information regarding the error conditions, you can enable the probe in your service to turn on the diagnostic mode. The DataPower probe allows you to view the step-by-step progression of your policy rules. You can also use client side debugging via the browser tools. These techniques are described in Part 2 series in more detail.

Enabling the probe on the WTS causes the "error_description" property to be passed in the response when an error is encountered. Otherwise, only the "error" property is returned. To reach the probe settings for a Web Token Service, click the Probe Settings link on its configuration page.

Troubleshooting – invalid scope

If the OAuth client application, account-application, attempts to request an access token for resource "Account," the authorization server returns an "invalid_scope" error instead of an access token.

   curl -k https://<DataPower_IP>:5050/token  –-user account- application:passw0rd -d "grant_type=client_credentials&scope=Account"

Response:

   { "error":"invalid_scope" }

It occurs because the request scope Account is not valid. It does not match the allowed scope set in the account-application OAuth client profile.

Troubleshooting – unauthorized client

In the following example, the OAuth client application, account-application, attempts to request an access token, but the authorization server returns an "unauthorized_client" error (saying that it is not authorized for the resources).

   curl -k https://<DataPower_IP>:5050/token  -–user account- application:passw0rd -d "grant_type=client_credentials&scope=getAccount"

Response:

   {"error":"unauthorized_client", "error_description":"not authorized for the resources"}

It occurs when the client application (account-application) is not authorized to use the resource (getAccount). The client and the requested resource must be authorized in AAAInfo.xml. The error is resolved by adding account-application to the authorized list as shown in Step 2.

In the following example, the OAuth client application, account-application, attempts to request an access token, but the authorization server returns an "unauthorized_client" error (saying that the client_credentials grant is not supported).

   curl -k https://<DataPower_IP>:5050/token -d  "grant_type=client_credentials&scope=/getAccount"  –user account-application:passw0rd

Response:

   { "error":"unauthorized_client", "error_description":"client_credentials grant not supported" }

It occurs if the client credentials grant type is not selected in OAuth client profile. Thus, the client is not authorized to use method to request an access token. You can correct the error by selecting the client credentials grant type in the account-application OAuth client profile.

Troubleshooting – invalid client

The client application named hr-application attempts to request an access token, but the authorization server returns an "invalid_client" error instead of an access token.

   curl -k https://<DataPower_IP>:5050/token -d "grant_type=client_credentials& scope=/getAccount&client_id=hr-application&client_secret=passw0rd"

Response:

   { "error":"invalid_client", "error_description":"OAuth client is not configured" }

The error occurs because the client application, hr-application, is not registered with the authorization server. Check that the client is properly registered by verifying its OAuth client profile object listed in the OAuth client group definition as shown in Figure 4.

A similar error occurs when the provided client secret does not match the one in the OAuth client profile.

Client requests resource by sending an access token

To access a protected resource that uses an access token, the application client must present a valid access token to the enforcement point (MPGW service, listening on port 5051). Before including the access token in a curl command, you must URL-encode the token. For more information, see Online URL Encoding.

   curl –k https://<DataPower_IP>:5051/getAccount -H "Authorization: Bearer <Access_Token>"

The enforcement point validates the access token and returns a resource if the request is valid. If the access token sent by the client is valid, the protected resource (for example, a JSON response as shown below) on the resource server is returned back to the client.

   curl –k https://<DataPower_IP>:5701/getAccount -H "Authorization:Bearer  AAEFQWxpY2WOaEskZ5CHTvotHKGPCZghSw%2Fmj7%2FFEqJWlDgl3rlbiJ%2B h0X3KjTVEQk%2BME8tl4J1yc3xa1fvdXnjntLIOYa3P" {   "name": "myAccount",   "balance":1.00, }

If any error occurs when validating the resource request, an error code is returned via the WWW-Authenticate Response Header, or it is included in the response body. You can enable the probe in your service to turn on the diagnostic mode so that an error description is included in the response, in addition to a single error code, to help understand any errors that occurred. By the –v (verbose) flag on curl requests, you can view the returned headers as shown below:

   < HTTP/1.1 401 Unauthorized < Content-Type: text/xml < WWW-Authenticate: Bearer error="invalid_token",error_description="*[account-application]  Failed to verify oauth request signature*"
Troubleshooting – invalid token

A client application, account-application, attempts to access a resource. But, the enforcement point returns an invalid_token error (the access token has expired):

   curl –k https://<DataPower_IP>:5051/getAccount -H  "Authorization: Bearer <Access_Token>" –i

Response:

   HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer error="invalid_token",error_description="*[account-application]  access_token expired*" <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">   <env:Body>     <env:Fault>       <faultcode>env:Client</faultcode>       <faultstring>Failed to verify OAuth information.        (from client)</faultstring>     </env:Fault>   </env:Body> </env:Envelope>}

Thw error occurred because more than 3600 seconds (the default duration for our generated token) had passed since the time the access token was generated.

The client application, account-application, attempts to access a resource. However, the resource server returns an invalid token error (saying that the token signature verification failed).

   curl –k https://<DataPower_IP>:5051/getAccount -H "Authorization:  Bearer <Access_Token>" -i

Response:

   HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer error="invalid_token",error_description=  "*[account-application] Token signature verification failed*" <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">   <env:Body>     <env:Fault>       <faultcode>env:Client</faultcode>       <faultstring>Failed to verify OAuth information.        (from client)</faultstring>     </env:Fault>   </env:Body> </env:Envelope>

The error can occur when either the access token is not valid, or the access token is valid, but the shared secret in the OAuth client profile associated with the resource server is different from the one used to generate the access token on the authorization server. Ensure the access token is correct and check that the shared secret key in the OAuth client profile, account-application, is indeed shared between the token endpoint and the enforcement point.

Troubleshooting – insufficient scope

The client application, account-application, attempts to access the resource. However, the resource server returns an insufficient_scope error.

   curl –k https://<DataPower_IP>:5701/oauth -H "Authorization:Bearer  <Access_Token>" –i

Response:

   HTTP/1.1 403 Processed Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "error":"insufficient_scope", "error_description":"not authorized     for the resources" }

The error occurred because the scope requested (oauth) is different from the scope granted by the resource owner (getAccount). It is only enforced if you follow the optional Step 5 near Figure 11 for the Resource Extraction tab of the AAA policy. If you do not select "URL sent by client", the URL is not checked and the above request succeeds.

When URL sent by client is checked for the Resource extraction phase for the endpoint server AAA policy, it is important that the requested scope in the token request includes the leading slash. That's because the enforcement point compares the URL with the requested OAuth scope that is encoded in the access token. If they don't match, the resource request is denied.

Conclusion

Part 5 of the article series described how to use and implement the client credentials grant type in DataPower. It demonstrated how to configure DataPower as an OAuth authorization server that issues access tokens. It then showed how to configure DataPower as the enforcement point for resource server to validate access tokens. The request and response examples were provided to demonstrate troubleshooting techniques.

Acknowledgments

The author would like to thank Shiu-Fun Poon and John Rasmussen for their review of the article.

IBM WebSphere DataPower SOA Appliance HandbookIETF Web Authorization Protocol document (oauth)Gibson Research Corporation: Perfect Passwordsstring-functions.com: Online URL EncodingWebSphere DataPower Knowledge CenterWebSphere DataPower library

[{"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SS9H2Y","label":"IBM DataPower Gateway"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB45","label":"Automation"}}]

Document Information

Modified date:
25 July 2022

UID

ibm11109499