Explains what the ForgeRock Identity Microservices do, and how to start using them.

Preface

ForgeRock Identity Platform™ is the only offering for access management, identity management, user-managed access, directory services, and an identity gateway, designed and built as a single, unified platform.

The platform includes the following components that extend what is available in open source projects to provide fully featured, enterprise-ready software:

  • ForgeRock Access Management (AM)

  • ForgeRock Identity Management (IDM)

  • ForgeRock Directory Services (DS)

  • ForgeRock Identity Gateway (IG)

  • ForgeRock Identity Message Broker (IMB)

This guide explains what the ForgeRock Identity Microservices do, and how you can use them with the ForgeRock Identity Platform (the Platform).

This document is not meant to serve as a statement of functional specifications. Software functionality may evolve in incompatible ways in major and minor releases, and occasionally in maintenance (patch) releases. Release notes cover many incompatible changes. If you see an incompatible change for a stable interface that is not mentioned in the release notes, please report an issue with the product documentation for that release. See Appendix A, "Getting Support".

Chapter 1. Overview of the ForgeRock Identity Microservices

A microservice is a modular, lightweight process or application designed to easily interact with other processes or applications. Microservice instances are commonly deployed in a group within a container—a unit dedicated to a business service such as ordering, billing and registration. These containers typically integrate with external services such as messaging, policy engines, and shared secret storage.

ForgeRock Identity Microservices protect access to applications in a service call chain. They do this by authenticating and propagating both service and user identities throughout the chain. Each microservice must prove its identity and be authorized to invoke other microservices.

Figure 1.1. Groups of Microservices Form a Service Call Chain
Microservice instances are commonly deployed in groups that form a chain.

1.1. Authenticating, Validating, and Exchanging Security Tokens

The Identity Microservices are REST-enabled services that support The OAuth 2.0 Authorization Framework specification of the Internet Engineering Task Force (IETF). Each microservice is self-contained and runs in a stateless mode. The Identity Microservices are interoperable with the ForgeRock Identity Platform. You can deploy the Identity Microservices into containers that contain other interacting microservices.

The following Identity Microservices form a lightweight subset of the Platform:

Token Authentication Microservice

The Token Authentication Microservice generates security tokens you can use in service-to-service or user-to-service calls. This microservice supports the IETF specification OAuth 2.0 Client Credentials Flow . The authorization flow returns a stateless JSON Web Token (JWT) that the Token Validation Microservice can validate.

Token Validation Microservice

The Token Validation Microservice provides fast, local, and scalable access token validation. This microservice introspects and validates OAuth 2.0 tokens that adhere to one of the following IETF specifications:

Introspection requests adhere to the OAuth 2.0 Token Introspection request format.

Token Exchange Microservice

The Token Exchange Microservice lets the end user delegate access to another entity on behalf of the end user, or lets an entity impersonate the end user. Through delegation and impersonation, the Token Exchange Microservice propogates the user identity to the backend service. This microservice can also exchange one type of token for another type of security token. For example, it can convert a ForgeRock Access Manager stateful session token into a JWT.

The Token Exchange Microservice conforms to the OAuth 2.0 Token Exchange specification.

1.2. Coexisting with the ForgeRock Identity Platform

ForgeRock Identity Microservices are lightweight for optimum performance, and modular for optimum flexibility. You can deploy the microservices within containers, or as standalone applications. You can deploy multiple microservices in groups within containers. You can configure the microservices to communicate among containers, or to communicate directly with the Platform.

The Identity Microservices can coexist with ForgeRock Identity Platform as well as other microservices and applications you already have deployed.

Figure 1.2. Identity Microservices Coexist with The Platform
Identity Microservices Coexist with the Platform.

1.3. Microservices Process Flow

You can deploy a single Identity Microservice as a standalone module, or you can deploy them to work together. You can configure each microservice to work with non-ForgeRock client credential stores and policy engines. See Chapter 7, "Configuring a Client-Credentials Store" and Chapter 8, "Configuring Token Exchange Policies".

For illustration purposes, it's useful to see the role each microservice plays in fulfilling an end-user service request. The following figure illustrates the process flow among the Identity Microservices and ForgeRock Access Management.

Figure 1.3. Generating, Validating, and Exchanging Security Tokens
Microservices Process Flow

Chapter 2. Configuring the Identity Microservices

This chapter provides information common to all Identity Microservices.

Important

2.1. About the service.json File

Each microservice has a service.json containing JSON-formatted files for configuring the microservice. Many files have environment variable overrides so you can use the command line instead of having to open and edit a configuration file. Look for the service.json in the /path/to/microservice-name/conf directory where microservice-name is authn-microservice, token-validation-microservice, or token-exchange-microservice.

The mservice-name/conf/service.json file is your starting point for configuring a microservice. The service.json file indicates the variables you can configure and their default values. In the following example, the service.json file for the Token Authentication Microservice contains the setting for the CLIENT_CREDENTIAL_STORE variable. To find more information about this variable, you can look in the path/to/authn-microservice/conf/clientcredentialsstore.json file.

Example 2.1. Default service.json File for the Token Authentication Microservice
    /* Client Credentials Store to Use */
    "clientCredentialsStore" : "&{CLIENT_CREDENTIALS_STORE|json}",

    /* Provider Settings */
    "tokenProvider" : {
    "defaultExpirationSeconds" : "&{TOKEN_DEFAULT_EXPIRATION_SECONDS|3600}",
    "compression" : "&{TOKEN_COMPRESSION|false}",
    "issuer" : "&{TOKEN_ISSUER|https://example.com}",
    // optional comma-separated-list of additional audience claims (e.g., resource servers)
    "audience" : "&{TOKEN_AUDIENCE|}",
    // optional comma-separated-list of additional claims that can be provided by Client Credentials Store attributes
    "supportedAdditionalClaims" : "&{TOKEN_SUPPORTED_ADDITIONAL_CLAIMS|}"
    },

    /* Signing Settings */

    // JSON Web Key config for token-signature, which will default to no-signing when null (NOT for production use)
    "tokenSignature" : {
    // JSON Web Key used to sign tokens
    "jsonWebKey" : null,

    // JSON Web Key object, encoded as Base-64, which, if defined, will override the jsonWebKey attribute
    "jsonWebKeyBase64" : "&{TOKEN_SIGNATURE_JWK_BASE64|}"
    }
    }
    

2.2. Using Multiple Microservice Servers

When you want to run multiple Identity Microservices servers, you must use a unique port number for each server.

Procedure 2.1. To Change a Server Port Number
  1. Use an editor to open path/to/microservice-name/conf/boot.properties file.

  2. Edit port numbers to suit your needs, then save the file with the changes.

    For example, many procedures in this guide use port numbers other than the default port numbers.

    • In path/to/authn-microservice/conf/boot/boot.properties:

      microservice.port.http=8090
      microservice.port.https=8543
      microservice.port.mutualauth=8544
      microservice.auth.clientauthonlyports=8544
    • In path/to/token-validation-microservice/conf/boot/boot.properties:

      microservice.port.http=8091
      microservice.port.https=8643
      microservice.port.mutualauth=8644
      microservice.auth.clientauthonlyports=8644
    • In path/to/token-exchange-microservice/conf/boot/boot.properties:

      microservice.port.http=8092
      microservice.port.https=8743
      microservice.port.mutualauth=8744
      microservice.auth.clientauthonlyports=8744

2.3. Verifying Key Signatures

To authenticate, validate, and exchange a token, the Identity Microservices must have the keys that were used to sign the token. If the Identity Microservices, cannot access these keys, then the Identity Microservices cannot verify the token key signature. If the token key signature is not verified, then access to the requested resource will be denied.

You can use the AuthO JWT.io website to visually inspect access token attributes, and to verify that the token is signed.

2.4. Using a Salted-Hash Client-Secret Security Scheme

ForgeRock Identity Microservices supports using client-secret storage if both of the following are true:

  • The value is a Base-64 encoded string.

  • The underlying bytes contain the hashed client-secret and random integer salt that was used.

2.4.1. Supported Cyropgraphic Hash Algorithms

  • MD5

  • SHA-1

  • SHA-256 (Recommended)

  • SHA-384 (Recommended)

  • SHA-512 (Recommended)

2.4.2. Configuring the Salted-Hash Client-Secret Security Scheme

  • Make sure the file src/main/resources/clientsecret_saltedHash.json is in the application /conf directory.

  • Set the CLIENT_SECRET_SECURITY_SCHEME environment variable to saltedHash.

    See the clientcredentials.* files in the path/to/microservice-name/conf directory, directory where microservice-name is authn-microservice, token-validation-microservice, or token-exchange-microservice.

  • The JSON file contains an algorithm field which must contain one of the supported algorithms listed in Section 2.4.1, "Supported Cyropgraphic Hash Algorithms". Set the CLIENT_SECRET_ALGORITHM environment variable to override the default value which is SHA-256. For example:

    {
          "algorithm" : "SHA-256"
    }

2.5. Reading Incoming Transaction IDs

The microservices assign each incoming HTTP request transaction an ID for audit logging purposes. The default is a UUID. ForgeRock Microservices and other products such as Access Management support propagation of a transaction ID between point-to-point service calls.

After you enable this feature, transaction IDs are read from the X-ForgeRock-TransactionId HTTP header.

You can set the following system property in one of two ways:

  • Edit the /path/to/microservice-name/conf/system .properties file, where microservice-name is authn -microservice, token-validation-microservice, or token -exchange-microservice:

    org.forgerock.http.TrustTransactionHeader=true
  • Before starting the microservice, set the TRUST_TRANSACTION_ID_HEADER environment variable:

    $ export TRUST_TRANSACTION_ID_HEADER=true

Chapter 3. Using the Authentication Microservice

The Authentication Microservice generates OAuth 2.0 access tokens and validates client credentials. The following figure depicts the Token Authentication Microservice in its most simple, standalone process flow.

Figure 3.1. Authenticating Client Credentials
Token Authentication Microservice Process Flow

3.1. Downloading and Starting the Token Authentication Microservice

You can deploy the Token Authentication Microservice in one of two ways:

Unzip a zip file unto a local computer system.

See Procedure 3.1, "To Download the Token Authentication Microservice" in this guide for download and startup instructions.

Deploy the microservice in a Docker container.

The Token Authentication Microservice comes with a Dockerfile so you can deploy the microservice in a Docker container. See docker_file_location.

You must build your own Docker image. For detailed information, see the Docker product documentation.

Procedure 3.1. To Download the Token Authentication Microservice
  1. Download the file authn-zip/target/authn-microservice-1.0.0-SNAPSHOT.zip from the following location: zip_file_location.

  2. Unzip the file. For example:

    $ unzip authn-zip/target/authn-microservice-1.0.0-SNAPSHOT.zip
Procedure 3.2. To Start the Authentication Microservice

Mimimum Java 8 must be enabled on your computer system.

  1. Set the following environment variables:

    1. Set the JAVA_HOME variable:

      $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
    2. $ export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
    3. Set the ISSUER_JWK_JSON_JWK_BASE64 variable:

      $ export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
  2. In the directory where you unzipped authn-zip/target/authn-microservice-1.0.0-SNAPSHOT.zip, run the startup script:

    $ ./authn-microservice/bin/startup.sh
       ...
      INFO: Service ready
      Service ready
  3. To verify the microservice is running, in a new terminal window:

    $ curl --insecure \
      --user info:info \
      --request GET \
      --url 'http://localhost:8080/authn/info/ping'
    {"_id":"","shortDesc":"Ready","state":"ACTIVE_READY"}
Procedure 3.3. To Stop and Remove the Microservice
  1. To stop the microservice, enter shutdown.

  2. To remove the microservice, in /path/to/auth-microservice:

    $ rm -r authn-microservice

3.2. Verifying Token Generation

You can use the default JSON configurations provided with the Identity Microservices to verify that the Token Authentication Microservice can generate a bearer token.

The Identity Microservices come with a JSON file containing sample client credentials for demonstration purposes. See path/to/authn-microservice/conf/clientcredentials_json.json. The following procedure uses the client1 account to generate a bearer token.

Procedure 3.4. To Verify Token Generation
  1. In the file /path/to/authn-microservice/conf/boot/boot.properties, change the Token Authentication Microservice port number to 8090.

    For this example, and for other examples in this guide, the default port number is changed to 8090. See Section 2.2, "Using Multiple Microservice Servers"for more information.

  2. In the directory /path/to/authn-microservice, start the Token Authentication Microservice.

    1. Set the following environment variables:

      $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
      
        export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
      
        export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
    2. Run the Token Authentication Microservice startup script:

      $ ./authn-microservice/bin/startup.sh

      To verify that the microservice is running:

      $ curl --insecure \
        --user info:info \
        --request GET \
        --url 'http://localhost:8090/authn/info/ping'
         ...
        INFO: Service ready
        Service ready
  3. Generate a bearer token.

    In this example, a client service request specifies the client credential grant type, and the example scope. A bearer token is returned.

    $ curl -k -u client1:client1 -X POST \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials&scope=example" \
      "http://localhost:8090/service/access_token"
    {"access_token":"eyJ0eXAiOiJKV1QiLCJ6aXAiOiJOT05FIiwiYWxnIjoib
     m9uZSJ9.eyJzdWIiOiJ1c2VyLjAiLCJhdWQiOiJpbWFnZSIsInNjcCI6WyJyZ
     XNvdXJjZV93cml0ZSIsInJlc291cmNlX3JlYWQiXSwiaXNzIjoiaHR0cHM6Ly
     9leGFtcGxlLmNvbSIsImV4cCI6MTUwMDU4ODgzOCwiaWF0IjoxNTAwNTg1MjM
     4fQ.",
  4. (Optional) To visually inspect the bearer token, copy the access token portion of the computer output.

    1. Using a browser, go to the URL https://jwt.io.

    2. Paste the access token text into the Encoded frame of the jwt .io web page.

3.3. Example Token Authentication Microservice Endpoints

In the following example, a client service access the ping endpoint using the info user account:

$ curl --insecure \
  --user info:info \
  --request GET \
  --url 'http://localhost:8090/authn/info/ping'

In this example, the client service request results in all scopes being applied:

$ curl --insecure \
  --user client1:client1 \
  --request POST \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data "grant_type=client_credentials" \
  "http://localhost:8090/service/access_token"  

In this example, the client service request specifies the client_credential grant type and the example scope.

$ curl --insecure \
  --user client1:client1 \
  --request POST \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data "grant_type=client_credentials&scope=example" \
  "http://localhost:8090/service/access_token"

In this example, the client service request returns an error.

$ curl --insecure \
  --user client1:client1 \
  --request POST \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data "grant_type=client_credentials&scope=the_unknown_scope" \
  "http://localhost:8090/service/access_token"

3.4. Configuring the Token Authentication Microservice

This section provides configuration information specific to the Token Authentication Microservice. For important information common to all Identity Microservices, see Chapter 2, "Configuring the Identity Microservices".

3.4.1. Setting Environment Variables

The following table provides information about Token Authentication Microservice environment variables.

Table 3.1. Envivronment Variables for the Token Authenticaction Microservice
NameDescription
JAVA_HOMEAbsolute directory path to Java home
INFO_ACCOUNT_PASSWORD

Password for the info user account

In the authn-microservice directory see /conf/authentication.json and /script/access.js.

METRICS_ACCOUNT_PASSWORD

Password for the metrics user account

In the path/to/authn-microservice directory, see /conf/authentication.json and script/access.js.

CLIENT_CREDENTIALS_STORE

Client credentials store implementation to use

Options: json, ldap, mongodb, or cassandra

In the path/to/authn-microservice directory, see conf/service.json.

CLIENT_SECRET_SECURITY_SCHEME

Client secret security scheme implementation to use

Options: none or saltedHash

In the path/to/authn-microservice/conf directory, see the clientcredentials.* files. See also Section 2.4.2, "Configuring the Salted-Hash Client-Secret Security Scheme".

TOKEN_DEFAULT_EXPIRATION_SECONDS

Default number of seconds before an issued token expires

In the path/to/authn-microservice directory, see conf/service.json.

TOKEN_COMPRESSION

Token compression setting.

Set to true to enable token compression.

In the path/to/authn-microservice directory, see conf/service.json.

TOKEN_ISSUER

URI of the token issuer

In the path/to/authn-microservice directory, see conf/service.json.

TOKEN_AUDIENCE(Optional) Comma-separated list of additional token audience entries

These are often resource server URIs. By default, an audience is assigend for each token.

In the path/to/authn-microservice directory, see conf/service.json.

TOKEN_SUPPORTED_ADDITIONAL_CLAIMS

(Optional) Comma-separated list of attributes in the client-credentials store to add as claims to issued tokens

In the path/to/authn-microservice directory, see conf/service.json.

TOKEN_SIGNATURE_JWK_BASE64JSON Web Key object for JWT signing, encoded as a Base-64 string

In the path/to/authn-microservice directory, see conf/service.json.


3.4.2. Changing OAuth 2.0 Provider Settings

The OAuth 2.0 Provider contains a number of attributes related to how the OAuth2 Provider functions. You can configure the tokenProvider field in the file /path/to/authn-microservice/src/main/resources/conf/service.json.

The following table summarizes OAuth 2.0 provider settings and their defaults.

Table 3.2. OAuth 2.0 Provider Settings
NameDescription
defaultExpirationSecondsThe advertised duration (in seconds) an OAuth 2.0 Access Token should be considered valid for. Default: 3600
compressionIndicates whether the Stateless JWTs contained within the access token should be compressed. Use false for no compression (optimizes processing time); use true for compression (yields higher token volume). Default: false
issuerThe unique identifier (URL or string) that allows the issuing server to identify JWTs the server issued. Default: https://example .com
audience(Optional) Comma-separated list of additional audience claims such as resource servers
supportedAdditionalClaims(Optional) comma-separated list of additional claims that can be provided by client credentials store attributes

3.4.3. Changing Token Signing Settings

The tokenSignature field in the service.json file lets you to specify which JSON Web Key (JWK) settings to use when signing tokens. Token signing is disabled by default, but you must configure it to comply with OAuth 2.0 specifications.

The expected JSON format of the JWK settings is defined by JSON Web Key (JWK) . The Identity Microservices support RSA, EC, and HMAC signing, with the following algorithms:

  • HS256

  • HS384

  • HS512

  • RS256

  • ES256

  • ES384

  • ES512

In the following example, the "jsonWebKey" field is configured with an RSA public/private key-pair:

// JSON Web Key config for token-signature, which will default to no-signing when null (NOT for production use)
  "tokenSignature" : {
  // JSON Web Key used to sign tokens
  "jsonWebKey" : {
  "alg" : "RS256",
  "e" : "AQAB",
  "kty" : "RSA",
  "use" : "sig",
  "kid" : "my_key",
  "n" : "35cthtikgV55tEIZAivvzUDBBeEsck0TsE_k7dPuA-_idIEFqBR-uL0R9ayST4 \
   obkiDrlZ6_G-ZQQmHRb7Crf1FOGSqpot57Y-QfAN6giAyrv4MkJeh38bUuSkbkGkpt_9 \
   HxLfNAoe5I7OwJ8dPfy5CW5nzrjQq5DJXlxiXiiVE",
  "d" : "rPp6gE5uxp9erLROQL3ZIgQs0O2pwywaRVcqF0zUYTtfCR8gTy678xRjJpvB_c \
   MtHVpWqEROOblu8kxXCX-2zLBjVNlkp7Ky_JAlMwIdzhqCs9-osrmtci2quCEwQHwlmYV \
   LjBEDy8IOPKMBZCFcjw75TAxk7jWrGqOg_200eyE"
  },

  // JSON Web Key object, encoded as Base-64, which, if defined, will override the jsonWebKey attribute
  "jsonWebKeyBase64" : "&{TOKEN_SIGNATURE_JWK_BASE64}"
  }

3.4.3.1. To Provide the JWK as a Runtime Configuration Property

If you want to provide the JWK as a runtime configuration property, you can configure the jsonWebKeyBase64 field. You can populate this field by setting a value for TOKEN_SIGNATURE_JWK_BASE64 as either a Java command-line property, or as an environment variable. This field takes priority over jsonWebKey and must contain a Base-64 encoded representation of the same JSON format for JWK configuration.

For example, first save the following HMAC signing settings in a UTF-8 encoded text file named hmac_jwk.json:

{
   "kid" : "my_hmac_key",
   "kty" : "OCT",
   "alg" : "HS256",
   "k" : "FdFYFzERwC2uCBB46pZQi4GG85LujR8obt-KWRBICVQ"
   }

Then you can use OpenSSL to base 64-encode this file without newlines. Run the following command:

$ openssl base64 -A -in hmac_jwk.json -out hmac_jwk_base64.txt

3.4.3.2. To set the TOKEN_SIGNATURE_JWK_BASE64 Environment Variable

$ export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==

Chapter 4. Using the Token Validation Microservice

The Token Validation Microservice introspects and validates OAuth 2.0 tokens. The following figure depicts the Token Validation Microservice in its most simple, standalone process flow.

Figure 4.1. Validating an OAuth 2.0 Token
Client requests OAuth 2.0 token validation. The Token Validation Microservice validates and verifies the token.

You can configure the Token Validation Microserviceto introspect a bearer token generated by any OAuth 2.0 supported authorization server.

4.1. Downloading and Starting the Token Validation Microservice

You can deploy the Token Validation Microservice in one of two ways:

Unzip a zip file unto a local computer system.

See Procedure 4.1, "To Download the Token Validation Microservice" in this guide for download and startup instructions.

Deploy the microservice in a Docker container.

The Token Validation Microservice comes with a Dockerfile so you can deploy the microservice in a Docker container. See docker_file_location .

You must build your own Docker image. For detailed information, see the Docker product documentation.

Procedure 4.1. To Download the Token Validation Microservice
  1. Download the file token-validation-zip/target/token-validation-microservice-1.0.0-SNAPSHOT.zip from the following location: zip_file_location.

  2. Unzip the file. For example:

    $ unzip token-validation-microservice-1.0.0-SNAPSHOT.zip
Procedure 4.2. To Start the Token Validation Microservice

Mimimum Java 8 must be enabled on your computer system.

  1. Set the following environment variables:

    • Set the JAVA_HOME variable:

      $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
    • Set the TOKEN_SIGNATURE_JWK_BASE64 variable:

      $ export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
    • Set the ISSUER_JWK_JSON_JWK_BASE64 variable:

      $ export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
  2. In the directory where you unzipped token-validation-microservice-1.0.0-SNAPSHOT.zip, run the startup script:

    $ ./token-validation-microservice/bin/startup.sh
    ...
      INFO: Service ready
      Service ready
  3. To verify the microservice is running, in a new terminal window:

    $ curl --insecure \
      --user info:info \
      --request GET \
      --url 'http://localhost:8080/validation/info/ping'
      {"_id":"","shortDesc":"Ready","state":"ACTIVE_READY"}

    In this example, a client service accesses the ping endpoint using the user-account account.

Procedure 4.3. To Stop and Remove the Microservice
  1. To stop the microservice, enter shutdown.

  2. To remove the microservice, in /path/to/token-validation-microservice:

    $ rm -r token-validation-microservice

4.2. Verifying Token Introspection

You can use the default JSON configurations provided with the Identity Microservices to verify introspection in the Token Authentication Microservice and the Token Validation Microservice. First use the Token Authentication Microservice to generate a bearer token. Then use the Token Validation Microservice to validate the token.

Important

The Token Authentication Microservice and Token Validation Microservice must use the same JSON Web Key for token signing and validation. See step 2a in the following procedure.

The Token Authentication Microservice comes with a sample client credentials for demonstration purposes. See path/to/authn-microservice/conf/clientcredentials_json.json. The following procedure uses the client1 account to generate a bearer token. The client3 account scope field is set to introspect for the bearer account.

In the file path/to/token-validation-microservice/conf/service.json, the requiredBearerScope field is set to the default value introspect Only bearer tokens with the requiredBearerScope will be allowed to perform token introspection.

Procedure 4.4. To Verify Token Introspection

Note

This procedure uses the jq JSON processor for parsing and formatting JSON. See https://stedolan.github.io/jq/ for information about downloading and using jq.

  1. Ensure that the Token Authentication Microservice and Token Validation Microservice use unique port numbers. For this example:

    • Set the following port numbers for the Token Authentication Microservice in the file /path/to/authn-microservice/conf/boot/boot.properties.

      microservice.port.http=8090
      microservice.port.https=8543
      microservice.port.mutualauth=8544
      microservice.auth.clientauthonlyports=8544
    • Set the following port numbers for the Token Validation Microservice in the file /path/to/token-validation-microservice/conf/boot/boot.properties.

      microservice.port.http=8091
      microservice.port.https=8643
      microservice.port.mutualauth=8644
      microservice.auth.clientauthonlyports=8644
  2. In the directory /path/to/authn-microservice, start the Token Authentication Microservice.

    1. Set the following environment variables:

      $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
      
        export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
      
        export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
    2. Run the Token Authentication Microservice startup script:

      $ ./authn-microservice/bin/startup.sh

      To verify that the microservice is running:

      $ curl --insecure --user info:info --request GET --url 'http://localhost:8090/authn/info/ping'
        ...
        INFO: Service ready
        Service ready
  3. In the directory path/to/token-validation-microservice, start the Token Validation Microservice.

    1. Set the following environment variables:

      $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
      
        export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
      
        export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
    2. Run the Token Validation Microservice startup script:

      $ ./token-validation-microservice/bin/startup.sh

      To verify that the microservice is running:

      $ curl --insecure \
        --user info:info \
        --request GET \
        --url 'http://localhost:8091/validation/info/ping'
       ...
       INFO: Service ready
       Service ready
  4. Generate a bearer token:

    $ curl -k -u client3:client3 -X POST \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials" \
      -d "scope=introspect" \
      "http://localhost:8090/service/access_token" > bearer_tok.json
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
      Dload  Upload   Total   Spent    Left  Speed
      100   807    0   761  100    46  62535   3780 --:--:-- --:--:-- --:--:-- 63416
  5. Generate a JSON Web Token (JWT):

    $ curl -k -u client1:client1 -X POST \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials" \
      "http://localhost:8090/service/access_token" > introspect_tok.json
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
      Dload  Upload   Total   Spent    Left  Speed
      100   809    0   780  100    29  69124   2570 --:--:-- --:--:-- --:--:-- 70909
          
  6. Set the BEARER_TOKEN variable:

    $ export BEARER_TOKEN=$(cat bearer_tok.json | jq -r .access_token)
  7. Set the INTROSPECT_TOKEN variable:

    $ export INTROSPECT_TOKEN=$(cat introspect_tok.json | jq -r .access_token)
  8. Execute introspection:

    $ curl -k \
    -d "token_type_hint=access_token&token=$INTROSPECT_TOKEN" \
    -H "Authorization: Bearer $BEARER_TOKEN" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -X POST "http://localhost:8091/service/introspect" | jq
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
      Dload  Upload   Total   Spent    Left  Speed
      100  1175  100   443  100   732  27171  44896 --:--:-- --:--:-- --:--:-- 45750
         {
         "active": true,
         "sub": "client2",
         "scp": [
         "default",
         "example"
         ],
         "auditTrackingId": "ed4d64f9-a7cd-4205-8198-96ba81897591",
         "iss": "https://example.com",
         "tokenName": "access_token",
         "token_type": "Bearer",
         "authGrantId": "9c0f2f6e-4916-4f53-a139-deedb696d565",
         "aud": "client1",
         "nbf": 1506020609,
         "scope": [
         "default",
         "example"
         ],
         "auth_time": 1506020609,
         "exp": 1506020669,
         "iat": 1506020609,
         "expires_in": 60,
         "jti": "dd87e732-e731-408e-b750-eabb4cf589a8",
         "cid": "client2"
         }

4.3.1. Example Token Validation Microservice Endpoints

4.3.1.1. Validating a Stateless OAuth 2.0 Access Token Issued By the Token Authentication Microservice

In these examples, the client validates a stateless OAuth 2.0 access token issued by the Token Authentication Microservice running on localhost:18080 to service user client3.

The following token request specifies the OAuth 2.0 client credentials flow. However, no matter which flow is used to issue the token, the Token Validation Microservice attempts to validate the token.

$ curl --insecure \
  --user client3:client3 --request POST \
  "http://localhost:18080/service/access_token?grant_type=client_credentials& \
  scope=introspect" > bearer_tok.json

Note that client3 could be configured in the client credential store with a special scope such as the introspect -only scope, for example. The introspect -only scope entitles a client to seek introspection for other tokens, but does not entitle the client to other functions such as exchange. If the scopes for client3 included the introspect -only scope AND the exchange function, then the client3 would be able to invoke the Token Exchange Microservice service.

In the following example, client1 could be a another microservice, or a user whose token you want to introspect using the Token Validation MS. First, you must generate an access token using the Token Authentication Microservice:

$ curl --insecure \
  --user client1:client1 \
  --request POST \
    "http://localhost:18080/service/access_token?grant_type=client_credentials" > introspect_tok.json

  export CLIENT3_TOKEN=$(cat bearer_tok.json | jq --raw-output .access_token)
  export CLIENT1_TOKEN=$(cat introspect_tok.json | jq --raw-output .access_token)

Then you can invoke the Token Validation Microservice. In following example, the client sends a validation request to the Token Validation Microservice running on localhost:28080. The request includes the client1 access token to be introspected, and the bearer token from the service user client3.

# microservice-token-validation
$ curl --insecure \
  --data "token_type_hint=access_token&token=$CLIENT1_TOKEN" \
  --header "Authorization: Bearer $CLIENT3_TOKEN" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --request POST "http://localhost:28080/service/introspect" | jq

4.3.1.2. Validating an AM-Issued OIDC ID Token

In these examples, the client sends a request to AM for an OpenID Connect (OIDC) ID token. Once AM issues the OIDC ID token, the token immediately goes to the Token Validation Microservice for validation. In this case, the Token Validation Microservice can locally validate a stateful token because the microservice has access to the public key.

The following token request specifies the OAuth 2.0 client credentials flow. However, no matter which flow is used to issue the token, the Token Validation Microservice attempts to validate the token.

$ curl --request POST \
   --user "myoidcclient1:myoidcclient1" \
   --data "grant_type=client_credentials&scope=openid%20resource_read" \
     "http://openam:80/openam/oauth2/realms/root/access_token" id_token .json

# export the ID_TOKEN as env variable
$ export ID_TOKEN=$(cat am_token.json | jq --raw-output .id_token)

Note that client3 could be configured in the client credential store with a special scope such as the introspect -only scope, for example. The introspect -only scope entitles a client to seek introspection for other tokens, but does not entitle the client to other functions such as exchange. If the scopes for client3 included the introspect -only scope AND the exchange function, then the client3 would be able to invoke the Token Exchange Microservice service.

# use the  authN service to get bearer token
$ curl --insecure \
  --user client3:client3 \
  --header "Content-Type:application/x-www-form-urlencoded" \
  --request POST \
    "http://localhost:18080/service/access_token?grant_type=client_credentials" > bearer_tok.json

# export BEARER_TOKEN as env var
export BEARER_TOKEN=$(cat bearer_tok.json | jq --raw-output .access_token)

Before invoking token validation, you must import the public key needed tovalidate the signature of the ID token. Then you can invoke the Token Validation Microservice running on localhost:28080. You must provide the bearer token from the service user, client3 in this example. You must also provide the AM-issued stateful access token of the user or client you want to introspect, myoidcclient1 in this example.

# invoke validation service which validates ID_TOKEN locally
$ curl  --verbose --insecure \
 --data "token_type_hint=id_token&token=$ID_TOKEN" \
 --header "Authorization: Bearer $BEARER_TOKEN" \
 --header "Content-Type:application/x-www-form-urlencoded" \
 --request POST "http://localhost:28080/service/introspect" | jq

The Token Validation Microservice can validate the ID token locally if one of these is true:

  • You have configured the AM's public JWK URI so the Token Validation Microservice can look up the public key and validate the signature.

  • You have imported into the Token Validation Microservice configuration the public key used by AM to sign the ID token.

4.3.1.3.  Validating an AM-Issued SSO Token

AM single sign-on tokens, known as SSO tokens, can be introspected using the Token Introspection service. AM SSO tokens can be either stateful or stateless and will function in the same way for the introspection process. See Section 4.3.2.2, " Configuring the Token Introspection Service ".

To use this mode, set the token_type_hint to openam_sso. In the following example, authentication with AM takes place using the demo account to acquire the SSO token. The SSO token can then be provided to the Token Validation Microsevice for validation.

$  curl --insecure \
  --request POST \
  --header "X-AM-Username: demo" \
  --header "X-AM-Password: changeit" \
  --header "Content-Type: application/json" \
  --data "{}" "http://openam.example.com/openam/json/authenticate" > openam_sso.json

$ export AM_SSO=$(cat openam_sso.json | jq .tokenId | sed -E
  s/\"//g)

# validate ACCESS_TOKEN
$ curl --insecure \
  --data "token_type_hint=openam_sso&token=$SSO_TOKEN" \
  --header "Authorization: Bearer $INTROSPECT_BEARER_TOKEN" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --request POST "http://introspection.example.com:8080/service/introspect" | jq
 

4.3.1.4.  Proxying Token Validation Requests to AM

Before you can proxy token validation requests to AM, you must configure the Token Validation Microservice, and then configure AM. See Chapter 6, "Configuring the Token Validation Microservice to Proxy Requests to AM". This section provides the following example endpoints:

4.3.1.4.1.  Validating a Stateless OAuth 2.0 Access Token Issued By AM

In these examples, the client requests a stateless OAuth 2.0 access token from AM. After AM generates the access token, the access token goes immediately to the Token Validation Microservice for validation.

The following token request specifies the OAuth 2.0 client credentials flow. However, no matter which flow is used to issue the token, the Token Validation Microservice attempts to validate the token.

# get AM access token using CC flow
$ curl --request POST \
  --user "myoidcclient1:myoidcclient1" \
  --data "grant_type=client_credentials&scope=openid%20resource_read" \
    "http://openam:80/openam/oauth2/realms/root/access_token"  > am_token.json

# export only the access_token from AM
  export AM_TOKEN=$(cat am_token.json | jq --raw-output .access_token)

In the following example, client3 is a service user who will be issued an acccess token by the Token Authentication Microservice running on localhost:18080.

You can configure the client3 in the client credential store with a special scope such as the introspect -only scope, for example. The introspect -only scope entitles a client to seek introspection for other tokens, but does not entitle the client to other functions such as exchange. If the scopes for client3 included the introspect -only scope AND the exchange function, then the client3 would be able to invoke the Token Exchange Microservice service.

# client3 (service user) authenticates
$ curl --insecure
  --user client3:client3
  --request POST \
   "http://localhost:18080/service/access_token?grant_type=client_credentials&scope=introspect" > bearer_tok.json

# export only the service user’s access token (happens to be client3 in this example)
$ export CLIENT3_TOKEN=$(cat bearer_tok.json | jq --raw-output .access_token)

After obtaining both access and bearer tokens, you can invoke the Token Validation Microservice running on localhost:28080. You must provide the bearer token from the service user, which is client3 in this example. You must also provide the AM-issued access token of the user or client you want to introspect, which is myoidcclient1 in this example.

# microservice-token-validation
$ curl --insecure \
  --data "token_type_hint=access_token&token=$AM_TOKEN" \
  --header "Authorization: Bearer $CLIENT3_TOKEN" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --request POST "http://localhost:28080/service/introspect" | jq

The Token Validation Microservice can validate the ID token locally if one of these is true:

  • You have configured the AM's public JWK URI so the Token Validation Microservice can look up the public key and validate the signature.

  • You have imported into the Token Validation Microservice configuration the public key used by AM to sign the ID token.

4.3.1.4.2. Validating a Stateful OAuth 2.0 Access Token Issued By AM

In these examples, the client requests a stateful OAuth 2.0 access token from AM. After AM generates the access token, the access token goes immediately to the Token Validation Microservice for validation.

The Token Validation Microservice cannot locally validate a stateful token issued by another OAuth 2.0 server. So in this case, the client must proxy the validation request to the AM OAuth 2.0 server.

The following token request specifies the OAuth 2.0 client credentials flow. However, no matter which flow is used to issue the token, the Token Validation Microservice attempts to validate the token.

# get OPENAM access token using CC flow
$ curl --request POST \
  --user "myoidcclient1:myoidcclient1" \
  --data "grant_type=client_credentials&scope=openid%20resource_read" \
  "http://openam:80/openam/oauth2/realms/root/access_token"  > am_token.json

# export only the access_token from AM
$ export AM_TOKEN=$(cat am_token.json | jq --raw-output .access_token)

In the following example, client3 is a service user who is issued an access token by the Token Authentication Microservice running on localhost:18080.

You could configureclient3 in the client credential store with a special scope such as the introspect -only scope, for example. The introspect -only scope entitles a client to seek introspection for other tokens, but does not entitle the client to other functions such as exchange. If the scopes for client3 included the introspect -only scope AND the exchange function, then the client3 would be able to invoke the Token Exchange Microservice service.

# client3 (service user) authenticates
$ curl --insecure \
  --user client3:client3 \
  --request POST \
  "http://localhost:8080/service/access_token?grant_type=client_credentials& \
  scope=introspect" > bearer_tok.json

# export only the service user’s access token (happens to be client3 in this example)
$ export CLIENT3_TOKEN=$(cat bearer_tok.json | jq --raw-output .access_token)

Before invoking token validation, you must configure the location of the AM server at Token Validation Microservice, including the OAuth 2.0 token introspection URL of the AM server. Then you can invoke the Token Validation Microservice running on localhost:28080. You must provide the bearer token from the service user, client3 in this example. You must also provide the AM-issued stateful access token of the user or client you want to introspect, myoidcclient1 in this example.

The Token Validation Microservice cannot locally validate a stateful token issued by another OAuth 2.0 server. So in this case, the Token Validation Microservice must proxy the validation request to the AM OAuth 2.0 server.

# microservice-token-validation
$ curl --insecure \
  --data "token_type_hint=access_token&token=$AM_TOKEN" \
  --header "Authorization: Bearer $CLIENT3_TOKEN" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --request POST "http://localhost:8080/service/introspect" | jq

4.3.2. Configuring the Token Validation Microservice

This section provides configuration information specific to the Token Validation Microservice. For important information common to all Identity Microservices, see Chapter 2, "Configuring the Identity Microservices".

4.3.2.1. Setting Environment Variables

Table 4.1. Envivronment Variables for the Token Validation Microservice
NameDescription
JAVA_HOMEAbsolute directory path to Java home
INFO_ACCOUNT_PASSWORDPassword for the info user account

In the /path/to/token-validation-microservice, see conf/authentication.json and script/access.js

.
METRICS_ACCOUNT_PASSWORDPassword for the "metrics" user account

In the /path/to/token-validation-microservice, see conf/authentication.json and script/access.js

ISSUER_JWK_STOREComma-separated, priority-ordered list of Issuer JSON Web Key Store implementations to use

Default: json

In the /path/to/token-validation-microservice, see conf/service.json.

INTROSPECTION_SERVICESComma-separated, priority-ordered list of Token Introspection API implementations to use such as json or openam

Default: json

In the /path/to/token-validation-microservice, see conf/service.json.

INTROSPECTION_REQUIRED_SCOPEScope required on authorization bearer token to perform token-introspection

In the /path/to/token-validation-microservice, see conf/service.json.


4.3.2.2.  Configuring the Token Introspection Service

The token introspection service reads any JWT provided to it, and introspects the claims defined in the JWT. This includes ID Tokens produced by the AM OpenID Connect provider. The token introspection service is embedded in the Token Validation Microservice and is backed by a JSON configuration file.

4.3.2.2.1.  About Signed ID Tokens

The JSON handler distinguishes between ID Tokens that are signed symmetrically and those that are signed asymmetrically. This handler will not attempt to introspect symmetrically signed ID Tokens because symmetrically signed ID Tokens can only be processed by the issuer. The JSON handler must be configured with the asymmetric signing keys that are used by the OIDC Provider. These typically are available in JWK format from the oauth2/connect/jwk_uri endpoint:

$ curl "http://example.forgerock.com:8080/openam/oauth2/connect/jwk_uri" | jq

The specific keys required must be provided in the issuerJsonWebKeyStore parameter. See Table 4.2, "Environment Variables" below.

4.3.2.2.2.  Configuring the JSON Token Introspection Service

Configure the JSON token introspection service by changing settings in the /path/to/conf/introspection_json.json file:

{
    // Comma-separated names of Issuer JSON Web Key Store implementations, which
     maps OAuth token issuers to JSON Web Keys
    "issuerJsonWebKeyStore" : "&{ISSUER_JWK_STORE|json}"
}

The following are environment variables that can be used to populate fields in conf/introspection_json.json .

Table 4.2. Environment Variables
NameDescription
ISSUER_JWK_STOREComma-separated, priority ordered list of Issuer JSON Web Key Store implementation to use, which is JSON by default. See path/to/conf/introspection_json.json below .

4.3.2.3. Configuring Token Signature Verification

The issuerJsonWebKeyStore field in the token-exchange-zip/src/main/resources/conf/service.json lets you configure which JWT settings to use when verifying token signatures for specific OAuth 2.0 Token Issuers. The default Issuer JSON Web Key Store is the json implementation which is defined in a JSON configuration file. For more information, see Section 4.3.2.4, "Configuring an Issuer JSON Web Key Store - JSON".

4.3.2.4. Configuring an Issuer JSON Web Key Store - JSON

This is an implementation of an Issuer JSON Web Key Store that is backed by a JSON configuration file. An Issuer JSON Web Key Store maps an OAuth 2.0 token issuer to one or more JSON Web Keys, used for token signing and/or encryption.

4.3.2.4.1. Settings

The following example uses the default value to configure a single Issuer, with an RSA key having Key ID kid of my_key.

Each Issuer/Key ID pair must be unique. If there is only a single token signature issued by the Issuer, then Key ID values are optional. Note that the JWT to be verified, whether it provides a Key ID or not, will require the same Key ID configuration within this service in order to perform the lookup. There is no fallback logic.

There can be one or many entries for a given issuer. But each entry only points to a single JSON Web Key configuration. For more examples of generating and configuring JSON Web Keys, see Chapter 3, "Using the Authentication Microservice"

In a container environment such as Docker/Kubernetes, you can set the optional ISSUER_JWK_JSON_CONFIG_PATH environment variable with the path to an external JSON configuration file for this service. The file must be simple JSON, without property-substitution values or inline comments.

{
      // (optional) path of JSON config file that overrides this config file, and must only contain simple JSON syntax;
      // property-substitution values and/or inline comments are not allowed
      "configOverridePath" : "&{ISSUER_JWK_JSON_CONFIG_PATH|}",

      // associates JSON Web Keys, used to verify token signatures, with OAuth 2.0 Issuers
      "issuerJsonWebKeys" : [
      // example entry, used for testing and demonstration
      {
      // Issuer URI to associate with the given JWK
      "issuerUri" : "&{ISSUER_JWK_JSON_ISSUER_URI|https://example.com}",

      // JSON Web Key used to verify token signatures, which should specify a unique Key ID ("kid") claim
      "jsonWebKey" : {
      "alg" : "RS256",
      "e" : "AQAB",
      "kty" : "RSA",
      "use" : "sig",
      "kid" : "my_key",
      "n" : "35cthtikgV55tEIZAivvzUDBBeEsck0TsE_k7dPuA-_idIEFqBR-uL0R9ayST4 \
      obkiDrlZ6_G-ZQQmHRb7Crf1FOGSqpot57Y-QfAN6giAyrv4MkJeh38bUuSkbkGkpt_9 \
      HxLfNAoe5I7OwJ8dPfy5CW5nzrjQq5DJXlxiXiiVE",
      "d" : "rPp6gE5uxp9erLROQL3ZIgQs0O2pwywaRVcqF0zUYTtfCR8gTy678xRjJpvB_c \
      MtHVpWqEROOblu8kxXCX-2zLBjVNlkp7Ky_JAlMwIdzhqCs9-osrmtci2quCEwQHwlmYV \
      LjBEDy8IOPKMBZCFcjw75TAxk7jWrGqOg_200eyE"
       },

      // JSON Web Key object, encoded as Base-64, which, if defined, will override the jsonWebKey attribute
      "jsonWebKeyBase64" : "&{ISSUER_JWK_JSON_JWK_BASE64|}"
    }
  ]
}
4.3.2.4.2. JWT Key Store Environment Variables

The application is configured with example settings, by default. You may need to provide values for the following environment variables for more complex demonstrations or production use.

Table 4.3. JWT Key Store Environment Variables
NameDescription
ISSUER_JWK_JSON_CONFIG_PATHFor any use. Full filesystem path to the JSON configuration for this service, but the JSON cannot contain property-substitution values or inline comments. This is useful in container environments.
ISSUER_JWK_JSON_ISSUER_URIFor demonstration use. Issuer URI to associate with a single configured JSON Web Key. See the conf/service.json file.
ISSUER_JWK_JSON_JWK_BASE64For demonstration use. JSON Web Key object, for JWT signature validation, encoded as a Base-64 string. See the conf/service.json file.

Chapter 5. Using the Token Exchange Microservice

The Token Exchange Microservice receives OAuth 2.0 tokens and exchanges them for tokens compatible with a particular service. For example, a client may require an ID Token instead of an SSO Token.

The Token Exchange Microservices produces a composite security token that carries two identities:

  • The identity of a user that has accessed a service such as a front-end service

  • The identity of the service itself that is trying to access a backend service

The following figure depicts the Token Exchange Microservice in its most simple, standalone process flow.

Figure 5.1. Exchanging an ID Token for an SSO Token
Token Exchange Process Flow

5.1. Downloading and Starting the Token Exchange Microservice

You can deploy the Token Exchange Microservice in one of two ways:

Unzip a zip file unto a local computer system.

See Procedure 5.1, "To Download the Token Exchange Microservice" in this guide for download and startup instructions.

Deploy the microservice in a Docker container.

The Token Exchange Microservice comes with a Dockerfile so you can deploy the microservice in a Docker container. See docker_file_location .

You must build your own Docker image. For detailed information, see the Docker product documentation.

Procedure 5.1. To Download the Token Exchange Microservice
  1. Download the file authn-zip/target/token-exchange-microservice-1.0.0-SNAPSHOT.zip from the following location: zip_file_location.

  2. Unzip the file. For example:

    $ unzip token-exchange-microservice-1.0.0-SNAPSHOT.zip
Procedure 5.2. To Start the Token Exchange Microservice

Mimimum Java 8 must be enabled on your computer system.

  1. Set the JAVA_HOME variable:

    $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
  2. Set the TOKEN_SIGNATURE_JWK_BASE64 variable:

    $ export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
  3. Set the ISSUER_JWK_JSON_JWK_BASE64 variable:

    $ export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
  4. In the directory where you unzipped token-exchange-microservice-1.0.0-SNAPSHOT.zip, run the startup script:

    $ ./token-exchange-microservice/bin/startup.sh
      ...
      INFO: Service ready
      Service ready
  5. To verify the microservice is running, in a new terminal window:

    $ curl --insecure \
      --user info:info \
      --request GET \
      --url 'http://localhost:8080/exchange/info/ping'
      {"_id":"","shortDesc":"Ready","state":"ACTIVE_READY"}

    In this example, a client service accesses the ping endpoint using the account named user-account.

Procedure 5.3. To Stop and Remove the Microservice
  1. To stop the microservice, enter shutdown.

  2. To remove the microservice, in the /path/to/token-exchange-microservice:

    $ rm -r token-exchange-microservice

5.2. VerifyingToken Exchange

Procedure 5.4. To Verify Token Exchange

Note

This procedure uses the jq JSON processor for parsing and formatting JSON. See https://stedolan.github.io/jq/ for information about downloading and using jq.

  1. Ensure that the Token Authentication Microservice and Token Exchange Microservice use unique port numbers. For this example:

    • Set the following port numbers for the Token Authentication Microservice in the file /path/to/authn-microservice/conf/boot/boot.properties.

            microservice.port.http=8090
            microservice.port.https=8543
            microservice.port.mutualauth=8544
            microservice.auth.clientauthonlyports=8544
    • Set the following port numbers for the Token Exchange Microservice in the file /path/to/token-exchange-microservice/conf/boot/boot.properties.

            microservice.port.http=8092
            microservice.port.https=8743
            microservice.port.mutualauth=8644
            microservice.auth.clientauthonlyports=8744
  2. In the directory /path/to/authn-microservice, start the Token Authentication Microservice.

    1. Set the following environment variables:

      $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
      
        export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
      
        export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
    2. Run the Token Authentication Microservice startup script:

      $ ./authn-microservice/bin/startup.sh

      To verify that the microservice is running:

      $ curl --insecure \
        --user info:info \
        --request GET  \
        --url 'http://localhost:8090/authn/info/ping'
        ...
        INFO: Service ready
        Service ready
  3. In the directory path/to/token-exchange-microservice, start the Token Exchange Microservice.

    1. Set the following environment variables:

      $ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
      
        export TOKEN_SIGNATURE_JWK_BASE64=ewogICAgImtpZCIgOiAibXlfaG1hY19rZXkiLAogICAgImt0eSIgOiAiT0NUIiwKICAgICJhbGciIDogIkhTMjU2IiwKICAgICJrIiA6ICJGZEZZRnpFUndDMnVDQkI0NnBaUWk0R0c4NUx1alI4b2J0LUtXUkJJQ1ZRIgp9Cg==
      
        export ISSUER_JWK_JSON_JWK_BASE64=$TOKEN_SIGNATURE_JWK_BASE64
    2. Run the Token Exchange Microservice startup script:

      $ ./token-exchange-microservice/bin/startup.sh

      To verify that the microservice is running:

      $ curl --insecure \
        --user info:info \
        --request GET \
        --url 'http://localhost:8092/exchange/info/ping'
        ...
        INFO: Service ready
        Service ready
  4. Generate a bearer token:

    $ curl --insecure \
      --user client3:client3 \
      --request POST \
      --header "Content-Type: application/x-www-form-urlencoded" \
      --data "grant_type=client_credentials" \
      --data "scope=exchange" "http://localhost:8090/service/access_token" > bearer_tok.json
      Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
      Dload  Upload   Total   Spent    Left  Speed
      100   798    0   754  100    44  73820   4307 --:--:-- --:--:-- --:--:-- 75400
  5. Generate a subject token:

    $ curl --insecure \
      --user client2:client2 \
      --request POST \
      --header "Content-Type: application/x-www-form-urlencoded" \
      --data "grant_type=client_credentials" \
      "http://localhost:8090/service/access_token" > subject_tok.json
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
      Dload  Upload   Total   Spent    Left  Speed
      100   809    0   780  100    29  69124   2570 --:--:-- --:--:-- --:--:-- 70909
       
  6. Set the EXHANGE BEARER_TOKEN variable:

    $ export EXCHANGE_BEARER_TOKEN=$(cat bearer_tok.json | jq -r .access_token)
  7. Set the EXHANGE SUBJECT_TOKEN variable:

    $ export EXCHANGE_SUBJECT_TOKEN=$(cat subject_tok.json | jq -r .access_token)
  8. Start token exchange:

    $ curl -k \
      -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&audience=resource1&subject_token=$EXCHANGE_SUBJECT_TOKEN&subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
      -H "Authorization: Bearer $EXCHANGE_BEARER_TOKEN" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -X POST "http://localhost:8092/service/tokensts" | jq
    
     % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
      Dload  Upload   Total   Spent    Left  Speed
      100  1465  100   635  100   830  64284  84025 --:--:-- --:--:-- --:--:-- 92222
      {
      "access_token":"eyJ0eXAiOiJKV1QiLCJ6aXAiOiJOT05FIiwiYWxnIjoib
     m9uZSJ9.eyJzdWIiOiJ1c2VyLjAiLCJhdWQiOiJpbWFnZSIsInNjcCI6WyJyZ
     XNvdXJjZV93cml0ZSIsInJlc291cmNlX3JlYWQiXSwiaXNzIjoiaHR0cHM6Ly
     9leGFtcGxlLmNvbSIsImV4cCI6MTUwMDU4ODgzOCwiaWF0IjoxNTAwNTg1MjM
     4fQ.",
     "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
      "token_type": "Bearer",
      "expires_in": 3210,
      "scope": "resource_write resource_read"
      }

5.3. Example Token Exchange Microservice Endpoints

In these examples, Alice is a service user. Alice logs into AM with a username and password.

The following command is a REST call to the authentication endpoint in AM, and returns a JSON object that can be parsed easily.

# get subject token for use with token exchange service
$ curl --request POST \
  --header "X-OpenAM-Username:Alice" \
  --header "X-OpenAM-Password: cangetinam" \
  --header "Content-Type: application/json"--data "{}" \
    http://openam:18080/openam/json/authenticate

# export received SSO_Token as the subject token- passed in to policy call
$ export EXCHANGE_BEARER_TOKEN=$(cat bearer_tok.json | jq --raw-output .access_token)

In the following example, client3 is a service user who will be issued an access token by the Token Authentication Microservice running on localhost:18080.

Note that client3 could be configured in the client credential store with a special scope such as the introspect -only scope, for example. The introspect -only scope entitles a client to seek introspection for other tokens, but does not entitle the client to other functions such as exchange. If the scopes for client3 included the introspect -only scope AND the exchange function, then the client3 would be able to invoke the Token Exchange Microservice service.

# get client bearer token from authn service
curl --insecure \
  --user client3:client3 \
  --request POST
    "http://localhost:18080/service/access_token?grant_type=client_credentials" > bearer_tok.json

# export client's bearer token as env var
$ export EX_BEARER_TOKEN=$(cat bearer_tok.json | jq --raw-output .access_token)

Before the Token Exchange Microservice can evaluate Alice’s entitlement on the resource, or audience requested, the microservice must obtain a policy service SSO token, also known as a session token, for itself. You must configure the following environment variables. These include the path to the Access Management authentication REST endpoint, and an administrator identity.

# export AM service account information - used to call policy endpoint
$ export EXCHANGE_OPENAM_AUTH_SUBJECT_ID=amadmin
  export EXCHANGE_OPENAM_AUTH_SUBJECT_PASSWORD=cangetinam
  export EXCHANGE_OPENAM_AUTH_URL=http://openam:80/openam/json/authenticate

You must also define the policy set in AM, as well as the the policy REST endpoint as in the following example. You have to restart the Token Exchange Microservice service for these environment variables to take effect.

# export policy set name for the exchange policies defined in AM
$ export EXCHANGE_OPENAM_POLICY_SET_ID=resource_policies
  export EXCHANGE_OPENAM_POLICY_URL=http://openam:80/openam/json/realms/root/policies

  

Each policy implementation supported by the Token Exchange Microservice is defined in its own JSON configuration file. This file describes the connection to the policy decision point (PDP), which is AM in this example, the service identity to use for establishing a connection to the PDP, the name of the policy set, and so forth. While the export commands above aim to do the same, you can save these directly into the file. See Section 2.1, "About the service.json File" for more information.

# ensure exchange policy mapping includes entry for audience or resource requested
exchangepolicy_openam.json

Once you have obtained Alice’s session token and have configured the connection to the PDP, you can invoke the Token Exchange Microservice which attempts to call the AM policy endpoint. AM then evaluates policy for Alice, and returns allowed scopes and attributes to the the Token Exchange Microservice. The Token Exchange Microservice creates and signs a new JWT.

# invoke the exchange microservice
$ curl --insecure \
   --data "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
   --data "resource=http://images.example.com:*/*" \
   --data "subject_token=$EX_SUBJECT_TOKEN" \
   --data "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
   --header "Authorization: Bearer $EX_BEARER_TOKEN" \
   --header "Content-Type: application/x-www-form-urlencoded" \
   --request POST "http://localhost:38080/service/tokensts" | jq

# response from exchange service
{
  "access_token":"eyJ0eXAiOiJKV1QiLCJ6aXAiOiJOT05FIiwiYWxnIjoib
   m9uZSJ9.eyJzdWIiOiJ1c2VyLjAiLCJhdWQiOiJpbWFnZSIsInNjcCI6WyJyZ
   XNvdXJjZV93cml0ZSIsInJlc291cmNlX3JlYWQiXSwiaXNzIjoiaHR0cHM6Ly
   9leGFtcGxlLmNvbSIsImV4cCI6MTUwMDU4ODgzOCwiaWF0IjoxNTAwNTg1MjM
   4fQ.",
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "resource_write resource_read"
 }

You can use the debugger at https://jwt.iojwt.io to inspect the token. The unpacked access_token will look like the following:

# the access_token returned on jwt.io
{
  "sub": "Alice",
  "aud": "images.example.com",
  "scp": [
    "resource_write",
    "resource_read"
  ],
  "iss": "https://example.com",
  "exp": 1500585110,
 "iat": 1500581510
}

In this example, the aud claim matches the resource requested in the payload to the Token Exchange Microservice. The allowed set of scp, or scopes, granted by PDP, which is AM in this case, are included in the new token.

5.4. Configuring the Token Exchange Microservice

This section provides configuration information specific to the Token Exchange Microservice. For important information common to all Identity Microservices, see Chapter 2, "Configuring the Identity Microservices".

5.4.1. Setting Environment Variables

The following table summarizes environment variables you can set for the Token Exchange Microservice.

Table 5.1. Envivronment Variables for the Token Exchange Microservice
NameDescription
JAVA_HOMEFor Non-Docker uses. Absolute directory path to Java home
Project_HOMEFor Docker uses. Absolute directory path to Java home

Absolute directory path containing all project directories/files for configuration

See docker-entrypoint.sh.

INFO_ACCOUNT_PASSWORDPassword for the info user account

In the /path/to/token-exchange-microservice, see conf/authentication.json and script/access.js.

METRICS_ACCOUNT_PASSWORDPassword for the metrics user account

In the /path/to/token-exchange-microservice, see conf/authentication.json and script/access.js

ISSUER_JWK_STOREComma-separated, priority-ordered list of Issuer JSON Web Key Store implementations to use

Default: json

In the /path/to/token-exchange-microservice, see conf/service.json.

TOKEN_EXCHANGE_POLICIES

Comma-separated names of Token-Exchange Policy implementations to use

Default: json

In the /path/to/token-exchange-microservice, see conf/service.json.

TOKEN_DEFAULT_EXPIRATION_SECONDS

Default number of seconds before an issued token expires

In the /path/to/token-exchange-microservice, see conf/service.json.

TOKEN_COMPRESSION

Set to true to enable token compression |

In the /path/to/token-exchange-microservice, see conf/service.json.

TOKEN_SIGNATURE_JWK_BASE64JSON Web Key object for JWT signing

Encoded as a Base-64 string.

In the /path/to/token-exchange-microservice, see conf/service.json.

TOKEN_EXCHANGE_REQUIRED_SCOPEScope required on bearer token to perform token-exchange

In the /path/to/token-exchange-microservice, see conf/service.json.


5.4.2. Configuring Token Signature Verification

The issuerJsonWebKeyStore field in the token-exchange-zip/src/main/resources/conf/service.json lets you configure which JWT settings to use when verifying token signatures for specific OAuth 2.0 Token Issuers. The default Issuer JSON Web Key Store is the json implementation which is defined in a JSON configuration file. For more information, see Section 4.3.2.4, "Configuring an Issuer JSON Web Key Store - JSON".

5.4.3. Configuring a Token Exchange Policy

The Token-Exchange Policy is a pluggable service that determines if a given token exchange may proceed. The service also determines what audience, scope, and so forth the generated token will have.

You can specify one or more Token-Exchange Policy implementations to use by setting the exchangePolicies field in the file path/to/token-exchange-microservice/conf/service.json. Use comma-separated values. For example: json,openam.

For more information, see Chapter 8, "Configuring Token Exchange Policies"

The following implementations come with Identity Microservices:

Chapter 6. Configuring the Token Validation Microservice to Proxy Requests to AM

Example endpoints for proxying token validation requests to AM are discussed in Section 4.3.1.4.1, " Validating a Stateless OAuth 2.0 Access Token Issued By AM " and Section 4.3.1.4.2, "Validating a Stateful OAuth 2.0 Access Token Issued By AM". Before you can proxy validation requests to AM, you must do the following:

  • Configure the Token Validation Microservice to Work With AM

  • Configure AM to Work With the Token Validation Microservice

6.1.  Configuring the Token Validation Microservice to Work With AM

You can change the settings by modifying the file path/to/mservices-validation/conf/introspection_openam.json, or you can set environment variables to populate the fields in the file.

The following is an example of an edited conf/introspection_openam.json file:

{
    // Credentials for an AM OAuth 2.0 client, supporting basic-auth, with "am-introspect-all-tokens" scope
    "clientId" : "&{INTROSPECTION_OPENAM_CLIENT_ID|introspect_svc}",
    "clientSecret" : "&{INTROSPECTION_OPENAM_CLIENT_SECRET|introspect_svc}",

    // URL for the AM introspect endpoint, without query parameters
    "introspectUrl" : "&{INTROSPECTION_OPENAM_URL|http://localhost:8080/openam/oauth2/realms/root/introspect}",

    // URL for the AM idtokeninfo endpoint, without query parameters
    "idtokeninfoUrl" : "&{INTROSPECTION_OPENAM_ID_TOKEN_INFO_URL|http://localhost:8080/openam/oauth2/realms/root/idtokeninfo}",

    // URL for the AM session endpoint, without query parameters
    "sessionUrl" : "&{INTROSPECTION_OPENAM_SESSION_URL|http://localhost:8080/openam/json/sessions}"
}
 

You can use the following environment variables to populate fields in conf/introspection_openam.json.

Table 6.1. Environment Variables Settings for Proxying Requests to AM
NameDescription
INTROSPECTION_OPENAM_CLIENT_ID Client ID (username) of AM OAuth 2.0 client account, supporting basic authenticationhn, with "am-introspect-all-tokens" scope
INTROSPECTION_OPENAM_CLIENT_SECRET Client Secret (password) of AM OAuth 2.0 client account
INTROSPECTION_OPENAM_URL URL for the AM introspect endpoint, without query parameters
INTROSPECTION_OPENAM_ID_TOKEN_INFO_URL URL for the AM OIDC ID Token endpoint
INTROSPECTION_OPENAM_SESSION_URL URL for the AM Session endpoint

6.2. Configuring AM to Work With the Token Validation Microservice

Procedure 6.1.  To Configure AM for Introspection
  1. Copy the AM WAR file into the Tomcat Application Server /webapps directory, and rename file to openam.war

  2. On the command line, execute catalina start.

  3. Add the OAuth 2.0 provider using the Service user interface. Be sure to save changes on each page after editing settings.

    • Toggle "Use Stateless Access & Refresh Tokens" depending on your needs.

    • On the Advanced tab, add needed scopes you need such as resource_read or resource_write.

    • Optionally, provide a means of signing tokens, such as "Token Signing HMAC Shared Secret" with HS256 "OAuth2 Token Signing Algorithm".

  4. Create a client account. Go to Applications > Agents > OAuth 2.0/OpenID Connect Client.

    • Client must have the "am-introspect-all-tokens" scope, or else AM can only introspect its own tokens.

    • Set the Token Endpoint Authentication Method to client_secret_basic.

Chapter 7. Configuring a Client-Credentials Store

Before you can enable the Identity Microservices to authenticate and authorize OAuth 2.0 acess tokens, you must already have a credentials store installed and provisioned.

7.1. Using Apache Cassandra as a Client Credentials Store

The Token Authentication Microservice comes with an example Cassandra credentials file you can use with the Example REST Endpoints and API Calls.

Procedure 7.1. To Set Up a Cassandra Client Credentials Store
  1. Download and install Apache Cassandra.

    See the Cassandra website for detailed download and installation instructions.

  2. To start Cassandra, run the following command:

    $ cassandra -f
  3. Run the following cqlsh command:

    $ cqlsh -e "SOURCE 'authn-client-credentials-store-cassandra/
        src/main/resources/cassandra_example_data.sql'"

    This command creates the forgerock_oauth keyspace, and populates the clients table with example data.

  4. Make sure src/main/resources/clientcredentials_cassandra.json is in the application /conf directory.

  5. In the conf/service.json file, set the CLIENT_CREDENTIALS_STORE environment variable to cassandra.

    The following are the default settings:

    {
         // Security Scheme used to encrypt client_secret values in the Client Credentials Store
         "clientSecretSecurityScheme" : "&{CLIENT_SECRET_SECURITY_SCHEME|none}",
    
         // Cassandra client configuration
         "clusterName" : "&{CREDENTIALS_STORE_CASSANDRA_CLUSTER_NAME|Test Cluster}",
         "contactPointCsv" : "&{CREDENTIALS_STORE_CASSANDRA_CONTACT_POINT_CSV|127.0.0.1}",
         "keyspace" : "&{CREDENTIALS_STORE_CASSANDRA_KEYSPACE|forgerock_oauth}",
         "table" : "&{CREDENTIALS_STORE_CASSANDRA_TABLE|clients}",
         "username" : "&{CREDENTIALS_STORE_CASSANDRA_USERNAME|}",
         "password" : "&{CREDENTIALS_STORE_CASSANDRA_PASSWORD|}",
         "fields" : {
         "clientId" : "&{CREDENTIALS_STORE_CASSANDRA_FIELDS_CLIENT_ID|id}",
         "clientSecret" : "&{CREDENTIALS_STORE_CASSANDRA_FIELDS_CLIENT_SECRET|secret}",
         "tokenExpirationSeconds" : "&{CREDENTIALS_STORE_CASSANDRA_FIELDS_TOKEN_EXP_SEC|tokenExpSeconds}",
         "scopes" : "&{CREDENTIALS_STORE_CASSANDRA_FIELDS_SCOPES|scopes}",
         "attributes" : "&{CREDENTIALS_STORE_CASSANDRA_FIELDS_ATTRIBUTES|attributes}"
         }
         }

The following table summarizes options you can use to customize your Cassandra client credentials store.

Table 7.1. Configuration Options for a Cassandra Client Credentials Store
NameDescription
CLIENT_SECRET_SECURITY_SCHEMEClient-Secret Security Scheme implementation to use. Options are none or saltedHash
CREDENTIALS_STORE_CASSANDRA_CLUSTER_NAME Cassandra cluster-name. The default is Test Cluster.
CREDENTIALS_STORE_CASSANDRA_CONTACT_POINT_CSVComma separated list of one or more Cassandra host IP addresses. The default is 127.0.0.1.
CREDENTIALS_STORE_CASSANDRA_KEYSPACECassandra keyspace-name. The default is forgerock_oauth.
CREDENTIALS_STORE_CASSANDRA_TABLECassandra table-name. The default is clients.
CREDENTIALS_STORE_CASSANDRA_USERNAME(Optional) Cassandra username.
CREDENTIALS_STORE_CASSANDRA_PASSWORD(Optional) Cassandra password.
CREDENTIALS_STORE_CASSANDRA_FIELDS_CLIENT_IDName of `clientId` field in your schema. The default is id.
CREDENTIALS_STORE_CASSANDRA_FIELDS_CLIENT_SECRETName of clientSecret field in your schema. The default is secret.
CREDENTIALS_STORE_CASSANDRA_FIELDS_TOKEN_EXP_SECName of tokenExpirationSeconds field in your schema. The default is tokenExpSeconds.
CREDENTIALS_STORE_CASSANDRA_FIELDS_SCOPESName of scopes field in your schema. The default is scopes.
CREDENTIALS_STORE_CASSANDRA_FIELDS_ATTRIBUTESName of attributes field in your schema. The default is default attributes.

7.2. Using ForgeRock Directory Services as a Client Credentials Store

The Token Authentication Microservice comes with an example LDIF file you can use with the Example REST Endpoints and API Calls.

Procedure 7.2. To Set Up Directory Services as a Client Credentials Store
  1. Install Directory Services.

    See the ForgeRock Directory Services Installation Guide for detailed download and pre-installation instructions.

    To start the setup program, run the following command:

    $ ./opendj/setup

    During installation, you may need to choose mappings for ports `4444` and `8443` which do not conflict with ports mapped by `microservice-authn`. You can safely use the default LDAP protocol related ports such as `1389`).

    When prompted, provide the following information:

    Provide the server's fully qualified host name [name.local]: localhost
    
         Administration connector port [4444]: 5444
    
         HTTPS port [8443]: 9443
  2. During installation, install the fr_ms_client_example.ldif sample file.

    When prompted, provide the following information:

    Prepare data storage now? (yes / no) [yes]:yes
          Data storage options:
    
          1)  Leave the data storage (backend) empty
          2)  Create only a base DN entry
          3)  Import data from an LDIF file
          4)  Import automatically-generated sample data
    
          Enter choice [1]: 3
    
    
          Specify the LDIF file path: /microservice-authn/authn-client-credentials-store-ldap/
                                         src/main/resources/fr_ms_client_example.ldif
    
          Provide the base DN for the directory data: [dc=example,dc=com]: dc=example,dc=com
    
          Data Storage Parameters
          ---------------------------------------------------------------------------
          Data storage option          Import data from /microservice-authn/authn-client-credentials-store
                                          -ldap/src/main/resources/fr_ms_client_example.ldif
          Base DN to create            dc=example,dc=com
          Data storage (backend) type  JE Backend
    
         Accept these choices and continue? (yes / no) [yes]:yes
  3. Enable the LDAP Client Credentials Store.

    Run Token Authentication Microservice startup script with the following environment variable setting:

    $ CLIENT_CREDENTIALS_STORE=ldap ./authn-microservice/bin/startup.sh

    This sets the CLIENT_CREDENTIALS_STORE environment variable to ldap. See conf/service.json.

7.2.1. Configuring the LDAP Client Credentials Store

Use conf/clientcredentials_ldap.json file to configure the LDAP Client Credentials store. See additional information following the example.

Example 7.1. Default example-clientcredentials_ldap.json File
     {
    "ldapClient" : {
    // LDAPv3 server host and port
    "host" : "&{CREDENTIALS_STORE_LDAP_HOST|localhost}",
    "port" : "&{CREDENTIALS_STORE_LDAP_PORT|1389}",

    // Indicates whether LDAP connections should be secured using SSL or StartTLS. See boot.properties
    // for truststore location and password configuration.
    //
    // Acceptable values are:
    //
    // "none"     - use plain LDAP connections (default)
    // "ssl"      - secure connection using LDAPS
    // "startTLS" - secure connection using LDAP+StartTLS
    "connectionSecurity": "&{CREDENTIALS_STORE_LDAP_CONNECTION_SECURITY|none}"
    },

    // Authentication policy must be one of "useLdapBind" or "useClientSecretSecurityScheme"
    "authenticationPolicy" : "&{CREDENTIALS_STORE_LDAP_AUTHN_POLICY|useLdapBind}",

    // Applies if authenticationPolicy == useLdapBind
    "useLdapBind" : {
    // The bindPassword is the client_secret
    // Required variables in expression string: %clientId%
    "clientIdBindDnTemplate" : "&{CREDENTIALS_STORE_LDAP_BIND_DN_TEMPLATE|uid=%clientId%,ou=fr_ms_client,dc=example,dc=com}"
    },

    // Applies if authenticationPolicy == useClientSecretSecurityScheme
    "useClientSecretSecurityScheme" : {
    // Security Scheme used to encrypt client_secret values in the Client Credentials Store
    "clientSecretSecurityScheme" : "&{CLIENT_SECRET_SECURITY_SCHEME|none}",

    // (optional) Distinguished name of the Directory object that the client wishes to bind as
    "bindDn" : "&{CREDENTIALS_STORE_LDAP_BIND_DN|}",

    // (optional) Password of the Directory object that the client wishes to bind as
    "bindPassword" : "&{CREDENTIALS_STORE_LDAP_BIND_PASSWORD|}",

    // Distinguished name that matches a single client record
    // Required variables in expression string: %clientId%
    "readEntryDn" : "&{CREDENTIALS_STORE_LDAP_READ_ENTRY_DN_TEMPLATE|uid=%clientId%,ou=fr_ms_client,dc=example,dc=com}"
    },

    // NOTE: default field mappings are from fr_ms_client_example.ldif
    "fields" : {
    "clientId" : "&{CREDENTIALS_STORE_LDAP_FIELDS_CLIENT_ID|uid}",
    "clientSecret" : "&{CREDENTIALS_STORE_LDAP_FIELDS_CLIENT_SECRET|userPassword}",
    "tokenExpirationSeconds" : "&{CREDENTIALS_STORE_LDAP_FIELDS_TOKEN_EXP_SEC|employeeNumber}",
    "scopes" : "&{CREDENTIALS_STORE_LDAP_FIELDS_SCOPES|carLicense}",
    // (optional) comma-separated names of attributes to copy into OAuth 2.0 Token claims, if the attributes are defined
    "additionalClaimsCsv" : "&{CREDENTIALS_STORE_LDAP_FIELDS_ADDITIONAL_CLAIMS_CSV|displayName}"
    }
    }
    

7.2.1.1. Additional Configuration Tips

  • The connectionSecurity value of ssl or startTLS requires that the issuer_ certificate for your LDAP server is located in a Java truststore.

  • Configure the Java truststore in conf/boot/boot.properties.

    • microservice.truststore.location : filesystem path to truststore

    • microservice.truststore.password : truststore password

    • microservice.truststore.type : truststore type (e.g., JKS)

  • When you want to authenticate LDAP server calls using the client_id and client_secret given in OAuth 2.0 token generation calls, use authenticationPolicy with value useLdapBind.

  • When you want to use an admin_ account for LDAP server authentication, and a pluggable clientSecretSecurityScheme to validate client_secret values, use authenticationPolicy with value useClientSecretSecurityScheme.

7.3. Using MongoDB as a Client Credentials Store

The Token Authentication Microservice comes with example data you can use with with MongoDB to use the Example REST Endpoints and API Calls.

Procedure 7.3. To Set Up a MongoDB Client Credentials Store
  1. Install MongoDB.

    See the MongoDB website https://docs.mongodb.com/manual/administration/install-community for detailed download and installation instructions.

  2. Create a data directory:

    $ mkdir -p ~/mongodb/data/db
  3. Start MongoDB:

    $ mongod --dbpath ~/mongodb/data/db
  4. Make sure the file clientcredentials_mongodb.json file is in the path/to/microservice-name/clientcredentials_mongodb.json directory.

  5. In conf/service.json, set the CLIENT_CREDENTIALS_STORE environment variable to mongodb.

Example 7.2. Example conf/service.json File
 {
    "connectionString" : "mongodb://localhost:27017",
    "database" : "forgerock_oauth",
    "collection" : "clients",
    "fields" : {
    "clientId" : "_id",
    "clientSecret" : "secret",
    "tokenExpirationSeconds" : "tokenExpSeconds",
    "scopes" : "scopes",
    "attributes" : "attributes"
    }
    }

The following table summarizes the options you can use to customize your MongoDB client credentials store.

Table 7.2. Environment Variables for MongoDB Client Credentials Store
NameDescription
CREDENTIALS_STORE_MONGODB_CONNECTION_STRINGMongoDB connectionString
CREDENTIALS_STORE_MONGODB_DATABASEMongoDB database name
CREDENTIALS_STORE_MONGODB_COLLECTIONMongoDB collection name
CREDENTIALS_STORE_MONGODB_FIELDS_CLIENT_IDName of clientId field in your schema
CREDENTIALS_STORE_MONGODB_FIELDS_CLIENT_SECRETName of clientSecret field in your schema
CREDENTIALS_STORE_MONGODB_FIELDS_TOKEN_EXP_SECName of tokenExpirationSeconds field in your schema
CREDENTIALS_STORE_MONGODB_FIELDS_SCOPESName of scopes field in your schema
CREDENTIALS_STORE_MONGODB_FIELDS_ATTRIBUTESName of attributes field in your schema
CLIENT_SECRET_SECURITY_SCHEMEClient-Secret Security Scheme implementation to use Options are none or saltedHash.

Chapter 8. Configuring Token Exchange Policies

This chapter provides information for configuring policies supported by the Token Exchange Microservice:

8.1. Configuring a JSON Policy

The JSON Token Exchange policy engine determines whether a token-exchange is allowed, and what will appear in the generated token.

The policy engine matches requested resource URI "patterns" to a given "audience" which will appear in the generated token. Alternatively, if the token exchange request specifies an "audience" but no resource URIs, then this policy will match that audience. Policy rules are not mutually exclusive. Multiple policies could match many requested resources or audiences, and the result will be merged together for the generated token.

8.1.1. JSON Token Exchange Policy Settings

You can override the following default JSON configuration either by modifying conf/exchangepolicy_json.json, or by setting the optional environment variable EXCHANGE_POLICY_JSON_CONFIG_PATH. This is the absolute filesystem path to JSON configuration for this service. The environment variable is useful in a container environment such as Docker Kubernetes. See conf/exchangepolicy_json.json for detailed information.

```json
{
    // (optional) path of JSON config file that overrides this config file, and must only contain simple JSON syntax;
    // property-substitution values and/or inline comments are not allowed
    "configOverridePath" : "&{EXCHANGE_POLICY_JSON_CONFIG_PATH|}",

    "resources" : [
        {
            // patterns to match against the requested resource (either exact-match, or prefix-match up to first *)
            "patterns" : [
                "http://resource1.example.com/*",
                "http://resource1.example.com:80/*",
                "https://resource1.example.com/*",
                "https://resource1.example.com:443/*"
            ],
            // audience associated with this policy
            "audience" : "resource1",
            // scopes provided when resource-patterns and/or audience match
            "scopes" : [
                "resource_read",
                "resource_write"
            ],
            // optional field, to override number of seconds until token expiration, or null
            "expirationSeconds" : 3210,
            // optional array of actor_token subjects allowed to act as actors, or null
            "allowedActors" : [ "client3" ],
            // (optional) additional claims to be copied into generated tokens, or null
            "additionalClaims" : {
                "exampleString" : "value",
                "exampleNumber" : 1,
                "exampleBoolean" : true,
                "exampleObject" : { "key" : "value" },
                "exampleArray" : [ "item" ]
            }
        }
    ]
}
```

8.2. Configuring an Access Management Policy

Token Exchange policy engine accepts an Access Management SSO token and request, then uses an AM Policy Set to access one or more resources. The policy engine then generates values for fields such as audience and scopeused in the generated token. The policy engine can configure the generated token to be the same as those generated by the Token Authentication Microservice. But it is important to note that the generated token is not an Access Management token.

The settings in the following sections map Access Management policy attributes to expected or optional values used in token exchange operations. You can include additional attributes for a given policy. Any additional attributes are automatically copied into the generated token as additional claims.

Any additional attributes can have values of JSON types: string, number, boolean, object, array, or null. When multiple policies match a token exchange request resource or audience, the attributes are merged together.

The logic for merging attributes is to add each unique attribute to an array. The policy engine attempts to prevent duplicates, but in practice may not always eliminate duplicates of complex JSON objects.

8.2.1. Access Management Policy Settings

You can configure the Access Management policy engine by changing settings in the conf/exchangepolicy_openam.json file.

Example 8.1. Default exchangepolicy_openam.json File
 {
     // Credentials for an AM "subject" account with permission to access the AM policy endpoint
     "authSubjectId" : "&{EXCHANGE_OPENAM_AUTH_SUBJECT_ID|exchange_svc}",
     "authSubjectPassword" : "&{EXCHANGE_OPENAM_AUTH_SUBJECT_PASSWORD|exchange_svc}",

     // URL for the AM authentication endpoint, without query parameters
     "authUrl" : "&{EXCHANGE_OPENAM_AUTH_URL|http://localhost:8080/openam/json/authenticate}",

     // URL for the AM policy-endpoint, without query parameters
     "policyUrl" : "&{EXCHANGE_OPENAM_POLICY_URL|http://localhost:8080/openam/json/realms/root/policies}",

     // AM Policy-Set ID
     "policySetId" : "&{EXCHANGE_OPENAM_POLICY_SET_ID|resource_policies}",

     // AM policy-endpoint response-attribute field-name containing "audience" values
     "audienceAttribute" : "&{EXCHANGE_OPENAM_POLICY_AUDIENCE_ATTR|aud}",

     // AM policy-endpoint response-attribute field-name containing "scope" values
     "scopeAttribute" : "&{EXCHANGE_OPENAM_POLICY_SCOPE_ATTR|scp}",

     // AM policy-endpoint response-attribute field-name containing the token's "subject" value
     "subjectAttribute" : "&{EXCHANGE_OPENAM_POLICY_SUBJECT_ATTR|uid}",

     // (optional) AM policy-endpoint response-attribute field-name containing "expires-in-seconds" values
     "expiresInSecondsAttribute" : "&{EXCHANGE_OPENAM_POLICY_EXPIRES_IN_SEC_ATTR|}",

     // Set to "true" to copy additional AM policy-endpoint response-attributes into generated token claims
     "copyAdditionalAttributes" : "&{EXCHANGE_OPENAM_POLICY_COPY_ADDITIONAL_ATTR|true}"
     }

8.2.2. To Customize the Access Management Policy

The following table summarizes options you can use in conf/exchangepolicy_openam.json.

Table 8.1. Access Management Policy Configuration Options
NameDescription
EXCHANGE_OPENAM_AUTH_SUBJECT_IDID or username for an AM subject account with permission to access the AM policy endpoint. Default: exchange_svc
EXCHANGE_OPENAM_AUTH_SUBJECT_PASSWORDPassword for an AM subject account with permission to access the AM policy endpoint. Default: exchange_svc
EXCHANGE_OPENAM_AUTH_URLURL for the AM authentication endpoint with no query parameters. Default: http://localhost:8080/openam/json/authenticate
EXCHANGE_OPENAM_POLICY_URLURL for the AM policy-endpoint with no query parameters Default: http://localhost:8080/openam/json/realms/root/policies
EXCHANGE_OPENAM_POLICY_SET_IDAM Policy-Set ID Default: resource_policies
EXCHANGE_OPENAM_POLICY_AUDIENCE_ATTRAM policy-endpoint response-attribute field-name containing audience values Default: aud)
EXCHANGE_OPENAM_POLICY_SCOPE_ATTRAM policy-endpoint response-attribute field-name containing scope values Default: scp
EXCHANGE_OPENAM_POLICY_SUBJECT_ATTRAM policy-endpoint response-attribute field-name containing the token subject value Default: uid
EXCHANGE_OPENAM_POLICY_EXPIRES_IN_SEC_ATTR(Optional) AM policy-endpoint response-attribute field-name containing expires-in-seconds values
EXCHANGE_OPENAM_POLICY_COPY_ADDITIONAL_ATTRSet to true to copy additional AM policy-endpoint response-attributes into generated token claims, or false to disable this feature Default: true

8.3. Configuring a JWT Policy

The Token Exchange Policy engine receives any token supported by an OAuth 2.0 token introspection service, and exchanges that token for a JSON Web Token (JWT).

8.3.1. JWT Token Exchange Policy Settings

The conf/resources/exchangepolicy_jwt.json configuration file requires an introspectUrl and the issuerJsonWebKeyStore field, which is currently only used to validate the optional actor_token signature. For example:

{
  // URL to OAuth 2.0 Token Introspection service
  "introspectUrl" : "&{EXCHANGE_JWT_INTROSPECT_URL|http://localhost:8080/service/introspect}",

  // Comma-separated names of Issuer JSON Web Key Store implementations, which maps OAuth 2.0 token issuers to JSON Web Keys
  // NOTE: this is currently only used to validate the optional actor_token
  "issuerJsonWebKeyStore" : "&{ISSUER_JWK_STORE|json}"
  }

Appendix A. Getting Support

For more information or resources about the Identity Microservices and ForgeRock Support, see the following sections:

A.1. Accessing Documentation Online

ForgeRock publishes comprehensive documentation online:

  • The ForgeRock Knowledge Base offers a large and increasing number of up-to-date, practical articles that help you deploy and manage ForgeRock software.

    While many articles are visible to community members, ForgeRock customers have access to much more, including advanced information for customers using ForgeRock software in a mission-critical capacity.

  • ForgeRock product documentation, such as this document, aims to be technically accurate and complete with respect to the software documented. It is visible to everyone and covers all product features and examples of how to use them.

A.2. Using the ForgeRock.org Site

The ForgeRock.org site has links to source code for ForgeRock open source software, as well as links to the ForgeRock forums and technical blogs.

If you are a ForgeRock customer, raise a support ticket instead of using the forums. ForgeRock support professionals will get in touch to help you.

A.3. How to Report Problems or Provide Feedback

If you have questions regarding ForgeRock Identity Platform that are not answered by the documentation, you can search for answers at the ForgeRock Knowledge Base. https://backstage.forgerock.com/knowledge/kb.

If you have a valid subscription with ForgeRock, report issues or reproducible bugs at https://bugster.forgerock.org/jira/browse/DOCS.

When requesting help with a problem, include the following information:

  • Description of the problem, including when the problem occurs and its impact on your operation

  • Description of the environment, including the following information:

    • Software versions of supporting components

    • Software release version

    • Any patches or other software that might be affecting the problem

  • Steps to reproduce the problem

  • Any relevant access and error logs, stack traces, or core dumps

A.4. Getting Support and Contacting ForgeRock

ForgeRock provides support services, professional services, training through ForgeRock University, and partner services to assist you in setting up and maintaining your deployments. For a general overview of these services, see https://www.forgerock.com.

ForgeRock has staff members around the globe who support our international customers and partners. For details, visit https://www.forgerock.com, or send an email to ForgeRock at info@forgerock.com.

Read a different version of :