Obtaining an Access Token by Using a Self-Signed Client Assertion

The client application uses a self-signed client assertion as part of the request to obtain the access token.

Instead of sending the client credentials, send the client assertion as part of the request for greater security. In Oracle Cloud, all OAuth clients are confidential by default and so their credentials (client_id and password) are never exposed directly. A client assertion is generated before requesting an access token. See Step-by-Step Workflow of the Client Credentials Grant to identify the claims that need to be part of the client assertion.

In the client credentials workflow, you obtain an access token by using a client assertion.

Parameters used in the access token request:
  • X-USER-IDENTITY-DOMAIN-NAME: The name of the identity domain.

  • Content-Type: The type of content that’s sent in the request. It is a URL-encoded application.

  • Request: The type of request that’s sent. In the example that follows, a POST request is used to obtain an access token. This is followed by the authorization server URL, which provides tokens.

  • grant_type: The grant type used to obtain the token. In the example that follows, the grant type is client credentials. The value of client_credentials is given for this grant type.

  • scope: The limit of a particular scope for an access token.

  • client_assertion_type: This specifies the type of client assertion that’s passed. In Oracle Cloud, it’s jwt_bearer.

  • client_assertion: The value of the client token obtained.

The client credentials are available in the form of a self-signed JSON web token (JWT) client assertion. This is sent to obtain an access token.

To obtain an access token by using a client assertion, use the following cURL command:

curl -i -H 'X-USER-IDENTITY-DOMAIN-NAME: OAuthTestTenant150'
-H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8'
--request POST https://<idm-domain>.identity.<data-center>.oraclecloud.com/oauth/tokens 
-d 'grant_type=client_credentials
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJ4NXQiOiJyb2NFQ2NaVDlheG5FdWpQMVVPQVo3ZGNyTmMiLCJraWQiOiJJX0FNX0dPT0
QiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJzdWIiOiJhNWQ1MzllYy05MDZmLTQzZDYtOGQ3Ny1hODYzYjh
kMzdjZTQiLCJpc3MiOiJJX0FNX0dPT0QiLCJvcmFjbGUub2ljLnRva2VuLnR5cGUiOiJDTElFTlRUT0tFTiIsImV4c
CI6NDU3OTI2NjA3NywicHJuIjoiYTVkNTM5ZWMtOTA2Zi00M2Q2LThkNzctYTg2M2I4ZDM3Y2U0IiwiaWF0IjoxNDI
1NjY2MDc3LCJvcmFjbGUub2ljLnRva2VuLnVzZXJfZG4iOiJ1aWQ9YTVkNTM5ZWMtOTA2Zi00M2Q2LThkNzctYTg2M
2I4ZDM3Y2U0LCBjbj10ZXN0ZXIgdGVzdGVyLCBvdT10ZXN0LCBvPW9yYWNsZSwgc3Q9Y2FsaWZvcm5pYSwgYz11cyJ
9.MHC9Cof6uaZGMbrKAbmdn36b-nHkI6HWq7A9ygba3VA3hsHRM3_hqZY_qXM1A9H585SVhipmi0RR9TNTINWstj2h
H6Z9WbATX6qJynSbyv8K7vb35dK2-awaGON9oTi2aPdApFkTiaX9r0-lvZSwVMbwx6ZPSIHSuxFMWvrpL58
&scope=http://www.example.com'

The output of the cURL command is:
{
"expires_in":3600,
"token_type":"Bearer",
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsIng1dCI6ImtoNlhyVE42V2p6dmhIOExrNnNLaWVpUD
VodyIsImtpZCI6Ik9BdXRoVGVzdFRlbmFudDE1MC5jZXJ0In0.eyJzdWIiOiJhNWQ1MzllYy05MDZmLTQzZDYtOGQ3Ny1h
ODYzYjhkMzdjZTQiLCJpc3MiOiJPQXV0aFRlc3RUZW5hbnQxNTAiLCJvcmFjbGUub2F1dGguc3ZjX3BfbiI6Ik9BdXRoVG
VzdFRlbmFudDE1MFNlcnZpY2VQcm9maWxlIiwiaWF0IjoxNDI1NjY2NTk4MDAwLCJvcmFjbGUub2F1dGgucHJuLmlkX3R5
cGUiOiJDbGllbnRJRCIsImV4cCI6MTQyNTY3MDE5ODAwMCwib3JhY2xlLm9hdXRoLnRrX2NvbnRleHQiOiJyZXNvdXJjZV
9hY2Nlc3NfdGsiLCJhdWQiOlsiaHR0cDovL3d3dy5leGFtcGxlLmNvbSJdLCJwcm4iOiJhNWQ1MzllYy05MDZmLTQzZDYt
OGQ3Ny1hODYzYjhkMzdjZTQiLCJqdGkiOiJmOTA3MTFlOS0xOTgxLTQ4YzItOGMwOS1kOTE1MzRjMGRiY2EiLCJvcmFjbG
Uub2F1dGguY2xpZW50X29yaWdpbl9pZCI6ImE1ZDUzOWVjLTkwNmYtNDNkNi04ZDc3LWE4NjNiOGQzN2NlNCIsIm9yYWNs
ZS5vYXV0aC5zY29wZSI6Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20iLCJ1c2VyLnRlbmFudC5uYW1lIjoiT0F1dGhUZXN0VG
VuYW50MTUwIiwib3JhY2xlLm9hdXRoLmlkX2RfaWQiOiIzMDE2NzQ1NTk1MzQ0NzA4MSJ9.I8u207Vmvt3qiPI8tBeU2-t
liGgyiXHLzJJ1sY_jvv-8B_irYjkMBjyC12RzLb2-S0fpcZwuycCEjI4TCfkvfe6qBWdyEJHBxF1ioaKUhOs7oXgNxYcmo
8ZkkcwjdAg9nR4hRZ9lFZcYZOuHcSXxP2qsbnodrTxa6DLihj7cbyTql0i0d3wZjPMq9MPU3OyM6mtPDqltNTKVU56r-X9
w23-MDguQGLSLFbbxpv6XgEo3eS6j1sfXfZZ9kPLwW-rSITOuqnmdq90IUsSh8Y4_wAg-IrClftA9iRZ6D7z46t5-koXSY
U_oh6FwHJA0nhU-wt1z4UnD3HB60xKhEX8F8A"
}

The JWT obtained can be decoded, and the claims in the access token can be viewed as follows:

Access token:
 {
 alg: "RS256",
 typ: "JWT",
 x5t: "kh6XrTN6WjzvhH8Lk6sKieiP5hw",
 kid: "OAuthTestTenant150.cert"
}.
{
 sub: "a5d539ec-906f-43d6-8d77-a863b8d37ce4",
 iss: "OAuthTestTenant150",
 oracle.oauth.svc_p_n: "OAuthTestTenant150ServiceProfile",
 iat: 1425666598000,
 oracle.oauth.prn.id_type: "ClientID",
 exp: 1425670198000,
 oracle.oauth.tk_context: "resource_access_tk",
 aud: [
  "http://www.example.com"
 ],
 prn: "a5d539ec-906f-43d6-8d77-a863b8d37ce4",
 jti: "f90711e9-1981-48c2-8c09-d91534c0dbca",
 oracle.oauth.client_origin_id: "a5d539ec-906f-43d6-8d77-a863b8d37ce4",
 oracle.oauth.scope: "http://www.example.com",
 user.tenant.name: "OAuthTestTenant150",
 oracle.oauth.id_d_id: "30167455953447081"
}.
[signature]

Audience and scope claims in the output:

The audience claim in an access token contains the API path of the resource. The oracle.oauth.scope claim contains the valid API path with the scope in the response. In the prior example, the incoming request has a scope of http://www.example.com. The client audience configuration has a value of http://www.example.com::*. The OAuth token service validates the incoming request scope with the value found in the client audience configuration. Because this is a valid request, the OAuth token service sends a valid access token in the response. In this case, the audience claim has a value of http://www.example.com, and the scope has a value of http://www.example.com.