OIC supports several different methods of OAuth-based authentication, such as authorization code, client credentials, and JWT user assertion. More details on these can be found in the following link.
In this blog, we describe the JWT user assertion concepts without getting too deep into the weeds.
Also, read along until the end of the blog for working examples for JWT authentication.
Key Points
Prerequisites
Private/Public Key
- JWT user assertion requires the use of a private and public key.
- This key is used to sign the payload needed to generate the JWT user assertion.
- You can generate a simple self-signed key pair using the keytool utility (can be found on any machine with JDK installed).
Oauth Client Application
- You register a confidential application with Oracle Identity Cloud Service for each Oracle Integration instance.
- This confidential application provides access to the OAuth-protected REST endpoints in OIC.
Steps for both prerequisites can be found here – Prerequisites for JWT User Assertion.
Tokens
JWT User Assertion
- The JWT is a signed JSON payload with data (claims) that can include the user name, target, and scopes required by the application API.
- This is the first token that must be generated.
- In order to create the JWT, we first need data that represents the claims.
- For OIC, the header section should consist of the following:
{
"alg": "RS256",
"typ": "JWT",
"kid": "<<certificateALIAS>>"
}
Where
- alg The signing algorithm MUST be RS256.
- kid specifies the key to use to verify the signature. Therefore, it must match with the uploaded certificate ALIAS in Oracle Identity Cloud Service.
- The payload section should consist of the following:
{
"sub": "ssaInstanceAdmin",
"jti": "8c7df446-bfae-40be-be09-0ab55c655436",
"iat": 1589889699,
"exp": 1589909699,
"iss": "d702f5b31ee645ecbc49d05983aaee54",
"aud": "https://identity.oraclecloud.com/"
}
Where:
- sub specifies the user name for whom user assertion is generated.
- jti is a unique identifier.
- iat is issued (epoch seconds).
- exp is the token expiry (epoch seconds).
- iss is the client ID.
- aud must include the Oracle Identity Cloud Service audience https://identity.oracle.com/.
- The header and payload sections are Base64-encoded and concatenated as Header.Payload.
Example:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik9JSldUIn0.eyJzdWIiOiJ1c2VybmFtZUBvcmFjbGUuY29tIiwianRpIjoiOGM3ZGY0NDYtYmZhZS00MGJlLWJlMDktMGFiNTVjNjU1NDM2IiwiaWF0IjoxNjY0NDY1MDEwLCJleHAiOjE2NjQ0NjU1NTAsImlzcyI6IjY4MDU5OTEyN2RkZDQ3NTkzZTQxNGQyYTg5ODg2ZCIsImF1ZCI6Imh0dHBzOi8vaWRlbnRpdHkub3JhY2xlY2xvdWQuY29tLyJ9
- This is then signed in the RS256 algorithm, using the private key that was generated earlier.
- The result is three Base64 strings separated by dots (.) in the format of Header.Payload.Signature.
Example:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik9JSldUIn0.eyJzdWIiOiJ1c2VybmFtZUBvcmFjbGUuY29tIiwianRpIjoiOGM3ZGY0NDYtYmZhZS00MGJlLWJlMDktMGFiNTVjNjU1NDM2IiwiaWF0IjoxNjY0NDY1MDEwLCJleHAiOjE2NjQ0NjU1NTAsImlzcyI6IjY4MDU5OTEyN2RkZDQ3NTkzZTQxNGQyYTg5ODg2ZCIsImF1ZCI6Imh0dHBzOi8vaWRlbnRpdHkub3JhY2xlY2xvdWQuY29tLyJ9.jaQ2NyGk8wOWWHMGi2QJTsYlKGcHrfqkvP2Gb8AlBbJDQy7NDonXh6YMcAe17iIVaOfH7lDgJyF95xPv3nPHdIezbqobHBck34yct6I6a_xpKcV5kmJfXLHeb9LenqZTbdMMQ95vlUL8R914AmE2TbwGqjl4XkIoADHDez7PVM2MwyIDSfEaQ6o7J05ES7wIgI9gGspQ5w-2Xem4GOare25FBo-LrgVADDiAhKUhSLNT6XISCMAHZ3L2J86cnRhU1fekr-DJYFyfDcgAZeQPSPETHGokBWYtC1K-2qIouODKBKBcooABYEh6YTkC7bdax5KqFFbvJmSfDEjyN3tZ4w
More information about JWT can be found here.
Working examples below will help with the creation of this token.
Access Token
Once the JWT user assertion is generated, it is time to request the access token from Oracle Identity Cloud Service.
The curl command is as follows.
curl -L -X POST 'https://<idcs-instanceid>.identity.oraclecloud.com/oauth2/v1/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'Authorization: Basic <base64-clientid-secret>' \ --data-urlencode 'grant_type=<grant type>' \ --data-urlencode 'assertion=<user assertion>' \ --data-urlencode 'scope=<app scope>' EXAMPLE: -------- curl -L -X POST 'https://idcs-df8f9e70673e4d51aaa9915ca7b2d.identity.oraclecloud.com/oauth2/v1/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'Authorization: Basic NjgwNTk5MTI3ZGRkNDc1Mzg5M2U0M4OTg4NmQ6YWRhMmM3NDktY2VlOC00NTEwLTk5MzctNTg2ZWQ3YTJhNDZi' \ --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \ --data-urlencode 'assertion=eyJhbGciOiJSUzIdWIiOiJ2ZXJub24uai5zYWxkYW5oYUBvcmFjbGUuY29tIiwiYXVkIjoiaHR0cHM6Ly9pZGVudGl0eS5vcmFjbGUuY29tLyIsImp0aSI6IjhjN2RmNDQ2LWJmYWUtNDBiZS1iZTA5LTBhYjU1YzY1NTQzNiJ9.LeSChf2xG28rbwiAJsP_PFsNafxS1iSNkn_xIu7JOW8Fm_ppd2V5UTt01rky18fbXwWSTU9BwCfEs9hFRkYXbH9YxSMZ0yfjz85ZbzgZJe4ZvGNvqFiMxYAMwP5W8DUi7FhPmzH-sT7V9x0y9NSyDzlNwqbdy92XHdz1nfjQj645QHAA8_md4O7K9pTdoYNtauAN01eYCUOr_yaBKhsZfX6hi07aUwRPBTO7AyMsbfk92u_Yk-1CUBIVx7ZPO7c52oO7oo-BhWGNjzm3hhN36avJ9-lAMqwxiH32qFsHOdezS-l8YouwC6pPq7sd5bKQlYvb9XrZo0CCv3sSaVwCvA' \ --data-urlencode 'scope=https://C900A16A892141C6B8A245553E127ACC.integration.ocp.oraclecloud.com:443urn:opc:resource:consumer::all'
Where
- <grant type> – urn:ietf:params:oauth:grant-type:jwt-bearer
- <base64-clientid-secret> – Base 64 encode clientId:ClientSecret
- <user assertion> – JWT user assertion generated above
- <app scope> – Scope added while creating the application in the client configuration section (ends with urn:opc:resource:consumer::all)
If authenticated successfully, you should now have an access token that can be used to access the protected resources.
{
"access_token": "eyJ4NXQjG...dfsdfsFgets2ed",
"token_type": "Bearer",
"expires_in": 3600
}
The curl command to access the protected API looks something like this.
curl -L -X GET 'https://OIC host/OIC endpoint' \ -H 'Authorization: Bearer eyJ4NXQjG...dfsdfsFgets2ed' EXAMPLE: -------- curl -L -X GET 'https://oicpm-oicpm-px.integration.ocp.oraclecloud.com:443/ic/api/b2b/v1/schemas' \ -H 'Authorization: Bearer eyJ4NXQjUzI1NiI6Il9CbW5LbUV4WlZR5MOm8p3fVy_B1KF-h56dFo-PuTLAt7ZOKCg-CprlBhNiJYamYG_VYVOmzZ_Tb0fRruZEk-toRhGzbo2jckwIGpP2DGse2O1hVfSFSJr0dOatPaQ'
Working Collateral
Here are a couple of resources that can help you create the JWT user assertion. These are meant to be starter codes that you are free to modify and enhance as per your requirements. They are not codependent.
Shell Script to Generate JWT User Assertion
- Find the generateJWTUserAssertion.sh script file attached.
OIC Integration Package
- Find the TestAPIwithJWT.par file. This package contains all the artifacts that are needed to create a JWT user assertion and request.
- Modify the connection details as needed.
- Ensure that the Integrations from the package are activated.
- Find the TestAPIwithJWTUserAssertion integration and run the integration.
- Switch to the Body tab in the test page, provide the payload in the following format, and click on Test.
-
{
“sub”: “username@oracle.com”,
“aud”: “https://identity.oracle.com/”,
“kid”: “OICJWT”,
“scope”: “https://C900A16A89C.integration.ocp.oraclecloud.com:443urn:opc:resource:consumer::all”,
“iss”: “680599127ddd4753893e489886d”,
“secret”: “—–BEGIN PRIVATE KEY—– 2nmGy5VfYNSVrbOIaSS8sOASslmcPRYwcYN4iWj5OIztO5PSyTl0tc2gnbdP4tQ+rjcRrG57L3vrvoXYfdblheipE5gkHmxYapZMJWk1jT0G54s58ziqwhyJ+PfbMnf88I1zRCDUqQ==—–END PRIVATE KEY—–“,
“jti”: “8c7df446-bfae-40be-be09-0ab55c655436”
}
-
1 Export the GetJWTUserAssertion library from the Libraries section.
2 Extract the script from the .jar file by renaming .jar to .zip file.
3 Edit the jwtOIC.js file and save it.
4 Create the .jar again with the same name as follows.
jar cvf GetJWTUserAssertion_01.00.0000.jar jwtOIC.js jsrsasign-latest-all-min.js
5 Update the library with the new .jar file.
