This article intends to exemplify how to use the /introspect endpoint with a service application using public key / private key client authentication method.
- Service Application Integration
- Public key / Private key client authentication
- /introspect endpoint
This testing method demonstrates how to use the private_key_jwt client authentication and verify if a Token is valid with the /introspect endpoint.
This scenario uses a Service Application with a public key / private key since the request contains scopes that can be granted by the Org Authorization Server only.
Retrieve the public key / private key from the Service Application in order to create the JWT Token used in the client_assertion. The Token can be created with tools like jwt.io. The Header, Payload, and Verify Signature sections have to be filled with the relevant data.
The aud claim needs to be adjusted to reflect the endpoint where it is about to be sent.
In this case, the aud claim has to be https://${subdomain}.okta.com/oauth2/v1/token.
Copy the Token generated in jwt.io and use it with the /token endpoint as the client_assertion parameter value:
curl --location 'https://${subdomain}.okta.com/oauth2/v1/token?client_assertion=${insertGeneratedTokenHere}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=okta.users.read okta.groups.read okta.idps.manage' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
The curl should return an Access Token along with token_type, expires_in, and scope values:
{
"token_type": "Bearer",
"expires_in": 3600,
"access_token": "eyJraWQiOiIzTjFVNlB2dnpmS21xWDVRLUFFNmlyTU96MEFXeGhU...",
"scope": "okta.users.read okta.groups.read okta.idps.manage"
}
In order to verify the validity with /introspect, the Access Token needs to be sent as a token parameter value along with a newly generated JWT Token. The aud claim needs to be adjusted to reflect the endpoint where it is about to be sent.
In this case, the aud claim has to be https://${yourDomain}.okta.com/oauth2/v1/introspect.
Use the new JWT Token to validate the Access Token returned from the /token endpoint:
curl --location 'https://${subdomain}.okta.com/oauth2/v1/introspect?client_assertion=${newJWTToken}' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=${AccessToken}' \
--data-urlencode 'token_type_hint=access_token' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer'
If the Access Token is valid, the response will contain "active": true along with other data about the Access Token:
"active": true,
"scope": "okta.users.read okta.groups.read okta.idps.manage",
"exp": 1731416981,
"iat": 1731413381,
"sub": "0oa5aqr7pwKCxZAhH0x7",
"aud": "https://${subdoamin}.okta.com",
"iss": "https://${subdoamin}.okta.com",
"jti": "AT.8GaLb97SoJGyNjLMKWcsHyMDbLMoTHoVe9chK1Flm5k",
"token_type": "Bearer",
"client_id": "0oa5aqr7pwKCxZAhH0x7"
}
