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.
-
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'
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:
{ 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
.