Using the REST STS in AM/OpenAM

This book provides information on using the REST STS (Secure Token Service) in AM/OpenAM.


How To

How do I transform an OIDC token to a SAML2 assertion in AM/OpenAM (All versions) using REST STS?

Last updated Feb 26, 2019

The purpose of this article is to provide information on configuring a REST STS (Secure Token Service) instance in AM/OpenAM for transforming an OpenID Connect (OIDC) token to a SAML2 assertion. This article assumes AM/OpenAM is acting as the OAuth Authorization server (OAuth2 provider), an OIDC token provider, and a REST STS consumer; it provides the necessary configuration steps for this setup, but you can exclude the relevant steps if you are using other providers in place of AM/OpenAM.


1 reader recommends this article

Overview

This article covers the following steps to configure the REST STS and then transform the OIDC token to SAML2:

  1. Create a REST STS instance
  2. Create a Service Provider
  3. Create an OAuth2 provider (skip this step if you are not using AM/OpenAM as the OAuth2 provider)
  4. Create an OIDC client (skip this step if you are not using AM/OpenAM as the OIDC server)
  5. Create an OIDC authentication module (skip this step if you are not using AM/OpenAM as the OIDC server)
  6. Transform an OIDC token to SAML2

Creating a REST STS instance

You can create a REST STS instance as follows (you can view example screenshots of this configuration in test_sts.pdf):

  1. Create a new REST STS instance using the console:
    • AM 6 and later console: navigate to Realms > [Realm Name] > STS and click Add REST STS.
    • Pre-AM 6 console: navigate to Realms > [Realm Name] > STS > Rest STS Instances and click Add.
  2. Complete the configuration of the STS instance; you should specify the following settings at a minimum (for settings that are specific to your environment, example values have been given instead): 
    • Persist Issued Tokens in Core Token Store: option selected. 
    • Supported Token Transforms:
      UNT -> SAML2; invalidate interim OpenAM session
      OPENIDCONNECT -> SAML2; invalidate interim OpenAM session
    • Deployment Url Element: a string that identifies the REST STS instance, for example: test-sts. This string is used in the REST STS instance's endpoint.
    • The SAML2 issuer Id: sp.example.com
    • Service Provider Entity Id:  http://sp.example.com:8080/openam - this should match the protocol://hostname:port/deploymentcontext
    • Token Lifetime (Seconds): 60000 - it is recommended to set this high to start with for testing purposes.
    • The id of the OpenIdConnect Token Provider: http://sp.example.com:8080/openam - this is the OpenID Connect agent name, which should also match the protocol://hostname:port/deploymentcontext.
    • Token Lifetime (Seconds): 60000 - again set high to start with for testing purposes.
    • Token signature algorithm: HMAC SHA 256
    • Client secret: the client secret used as the HMAC key - this is mandatory for HMAC-signed tokens.
    • The audience for issued tokens:  http://sp.example.com:8080/openam - this should match the protocol://hostname:port/deploymentcontext.
  3. Restart the web application container in which AM/OpenAM runs to complete this configuration.
Note

You can also create a REST STS instance via ssoadm as detailed in How do I add and configure a REST STS instance in AM/OpenAM (All versions) using ssoadm? - you should use the settings described above.

Creating a Service Provider

You can create a Service Provider as follows:

  1. Navigate to:  Realms > [Realm Name] > Common Tasks > Configure SAMLv2 Provider > Create Hosted Service Provider
    • Name: http://sp.example.com:8080/openam
    • New Circle of Trust: cot

Creating an OAuth2 provider

If AM/OpenAM is acting as the OAuth2 provider, you should create this in the same realm as you created the REST STS instance (you can view example screenshots of this configuration in oauth_provider.pdf): 

  1. Navigate to: Realms > [Realm Name] > Common Tasks > Configure OAuth Provider > Configure OAuth 2.0 and populate the relevant details.
  2. Navigate to: Realms > [Realm Name] > Services > OAuth2 Provider and specify the supported scopes. You may need to add this service if it does not already exist.

Creating an OIDC client

If AM/OpenAM is acting as the OIDC server, you should create an OIDC client in the same realm as you created the REST STS instance (you can view example screenshots of this configuration in client.pdf):  

  1. Create a new OIDC client using the console:
    • AM 5.5 and later console: navigate to Realms > [Realm Name] > Applications > OAuth 2.0 and click Add Client.
    • AM 5 and 5.1.x console: navigate to Realms > [Realm Name] > Applications > OAuth 2.0 and click New.
    • OpenAM 13.x console: navigate to: Realms > [Realm Name] > Agents > OAuth 2.0/OpenID Connect Client and click New.
  2. Complete the configuration of the OIDC client; you should specify the following settings at a minimum (for settings that are specific to your environment, example values have been given instead): 
    • Name: http://sp.example.com:8080/openam - this should match the protocol://hostname:port/deploymentcontext.
    • Scope(s): cn, openid
    • Default Scope(s): cn, openid
    • Token Endpoint Authentication Method: client_secret_post - you must select this option if you use scope=openid%20profile with the resource owner password credentials grant type otherwise you will get an error when you do a POST request to the oauth2/access_token endpoint (invalid_client error when requesting an OAuth 2.0 access token in AM (All versions) and OpenAM 13.x).
    • ID Token Signing Algorithm (AM / OpenAM 13.5) / ID Token Signed Response Algorithm (OpenAM 13.0): RS256 
Note

You can also create an OIDC client using REST as detailed in How do I create and update an agent in AM/OpenAM (All versions) using the REST API? - you should use the settings described above.

Creating OIDC authentication module

If AM/OpenAM is acting as the OIDC server, you should create an OpenID Connect id_token bearer authentication module in the same realm as you created the REST STS instance: 

Note

There is a known issue with creating and viewing the OpenID Connect id_token bearer type authentication module via the console in OpenAM 13.x: OPENAM-8290 (Impossible to create an 'OpenID Connect id_token bearer` module) so you should use the ssoadm instructions instead.

AM 5 and later console

  1. Navigate to: Realms > [Realm Name] > Authentication > Modules and click Add Module.
  2. Name the module oidc, select OpenID Connect id_token bearer and click OK. The module name must be oidc (all in lowercase) as this is used by REST STS to know which authentication context is used to validate the OpenID Connect token.
  3. Complete the configuration of the OpenID Connect id_token bearer authentication module; you should specify the following settings at a minimum (for settings that are specific to your environment, example values have been given instead):
    • OpenID Connect validation configuration type: client_secret
    • OpenID Connect validation configuration value: password
    • Name of OpenID Connect ID Token Issuer: http://sp.example.com:8080/openam/oauth2
    • Mapping of jwt attributes to local LDAP attributes: sub=uid
    • Audience name: myClient
    • List of accepted authorized parties: myClient

ssoadm

  1. Use the following ssoadm command to create the OpenID Connect id_token bearer type authentication module:
    $ ./ssoadm create-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m oidc -t OpenIdConnect
    replacing [adminID], [passwordfile] and [realmname] with appropriate values. The module name must be oidc (all in lowercase) as this is used by REST STS to know which authentication context is used to validate the OpenID Connect token.
  2. Create a data file (called data_file to match the next command) with the following contents, or download the sample data_file:
    openam-auth-openidconnect-crypto-context-value=http://sp.example.com:8080/openam/oauth2/.well-known/openid-configuration
    openam-auth-openidconnect-issuer-name=http://sp.example.com:8080/openam/oauth2
    openam-auth-openidconnect-audience-name=http://sp.example.com:8080/openam
    openam-auth-openidconnect-accepted-authorized-parties=http://sp.example.com:8080/openam
    You can add other attributes if required as per the available ones detailed in Authentication and Single Sign-On Guide › OpenID Connect id_token bearer Module.
Note

Setting openam-auth-openidconnect-crypto-context-type (OpenID Connect validation configuration type) to anything other than the default does not work. There is a known issue associated with the client_secret value: OPENAM-7887 (Unsupported Signing Algorithm, SHA256withRSA with Google issued JWT's).

  1. Run the following command to configure your new oidc module with these settings:
    $ ./ssoadm update-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m oidc -D data_file
    replacing [adminID], [passwordfile] and [realmname] with appropriate values.
  2. You can check the settings for your new oidc module using the following command if required:
    $ ./ssoadm get-auth-instance -u [adminID] -f [passwordfile] -e [realmname] -m oidc
    replacing [adminID], [passwordfile] and [realmname] with appropriate values.​

Transforming an OIDC token to SAML2

Restart your AM/OpenAM server before testing to ensure that all changes have been captured.

To perform the transformation, you make a REST call to the following endpoint:

/rest-sts/[instance]?_action=translate

where [instance] is the name of the REST STS instance, including the realm in which it exists. For example: employees/test-sts.

Example using curl

The following example obtains an OIDC token and then uses the REST STS instance (called test-sts in the employees realm) to transform that OIDC token to a SAML2 assertion: ​

  1. Request an OIDC token by making a REST call to the oauth2/access_token endpoint, which uses the client_secret_post authentication method. For example:
    $ curl -X POST -d '{ 
         "client_id=myClientID&client_secret=changeit&grant_type=password&username=jdoe&password=changeit&scope=openid%20profile" 
    }' http://host1.example.com:8080/openam/oauth2/access_token
    
    Example response:
    {"scope":"openid profile","expires_in":599,"token_type":"Bearer","id_token":"eyAidHlwIjogIkpXVCIsICJhbGciOiAiSFMyNTYiLCAiY3R5IjogIkpXVCIsICJraWQiOiAiYTM3ZjE3YTItNjkzMi00YjAxLWFkZDUtOTM1YmU0N2E3NTI3IiB9.eyAidG9rZW5OYW1lIjogImlkX3Rva2VuIiwgImF6cCI6ICJteU9BdXRoMkNsaWVudCIsICJzdWIiOiAiZGVtbyIsICJhdF9oYXNoIjogIkVxV1JzNzlDMUVMVHBYazd6MU9pYVEiLCAiaXNzIjogImh0dHA6Ly9vYXV0aDJwcm92aWRlci5leGFtcGxlLm5ldDo1ODA4MC9vcGVuYW0vb2F1dGgyIiwgImlhdCI6IDE0NDE3MzI4NTMsICJhdXRoX3RpbWUiOiAxNDQxNzMyODUzLCAiZXhwIjogMTQ0MTczMzQ1MywgInRva2VuVHlwZSI6ICJKV1RUb2tlbiIsICJyZWFsbSI6ICIvIiwgImF1ZCI6IFsgIm15T0F1dGgyQ2xpZW50IiBdLCAib3BzIjogIjVmOGMyYWUzLTdkOTctNDNmNi04NGQ3LTI4YjgzYjNjNmUxNSIgfQ.wDh5UET7KuDLWc-enRpkLigqttYZ14PG2UIbmHOgAaM","access_token":"238beab2-b545-4fee-80fa-63f224bc56f6"}
    
  2. Transform the received OIDC token to a SAML2 assertion by making a REST call to the /rest-sts/employees/test-sts?_action=translate endpoint. For example:
    $ curl -X POST -H "Content-Type: application/json" -d '{ 
         "input_token_state": { "token_type": "OPENIDCONNECT", "oidc_id_token": "eyAidHlwIjogIkp...-enRpkLigqttYZ14PG2UIbmHOgAaM" }, 
         "output_token_state": { "token_type": "SAML2", "subject_confirmation": "BEARER", "service_provider_assertion_consumer_service_url": "http://sp.example.com:8080/openam/users/metaAlias/sp" } 
    }' 'http://host1.example.com:8080/openam/rest-sts/employees/test-sts?_action=translate'
    
    Example SAML2 assertion returned:
    {"issued_token":"<saml:Assertion xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"s259f7ac265f109b3ddcc265267c3f3f3e80af4657\" IssueInstant=\"2015-09-08T17:21:27Z\" Version=\"2.0\">\n<saml:Issuer>ForgeRock</saml:Issuer><saml:Subject>\n<saml:NameID Format=\"urn:oasis:names:tc:SAML:1.0:nameid-format:unspecified\">jdoe</saml:NameID><saml:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\">\n<saml:SubjectConfirmationData NotOnOrAfter=\"2015-09-08T17:31:27Z\"/></saml:SubjectConfirmation>\n</saml:Subject><saml:Conditions NotBefore=\"2015-09-08T17:21:27Z\" NotOnOrAfter=\"2015-09-08T17:31:27Z\">\n<saml:AudienceRestriction>\n<saml:Audience>sp</saml:Audience>\n</saml:AudienceRestriction>\n</saml:Conditions>\n<saml:AuthnStatement AuthnInstant=\"2015-09-08T17:21:27Z\"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>"}
    
    

See Also

Using the REST STS in AM/OpenAM

invalid_client error when requesting an OAuth 2.0 access token in AM (All versions) and OpenAM 13.x

Security Token Service Guide

Related Training

N/A

Related Issue Tracker IDs

OPENAM-13337 (Upgrade OpenAM from 13.5.1 to AM 5.5.1 result in unable to obtain OAuth 2 access token)

OPENAM-8423 (Introduce "audience URL" attribute in OAuth2 client for Saml2GrantTypeHandler)

OPENAM-8290 (Impossible to create an 'OpenID Connect id_token bearer` module)

OPENAM-7887 (Unsupported Signing Algorithm, SHA256withRSA with Google issued JWT's)

OPENAM-6461 (Federation, SAE, & WSSAuthModule missing in new realm after default initial configuration)

OPENAM-6319 (OAuth2 scopes behaviour affected by the upgrade)



Copyright and TrademarksCopyright © 2019 ForgeRock, all rights reserved.
Loading...