Client authentication to /token through an incoming JSON Web Token
Security Verify Access OIDC Providers support client authentication to
/token through an incoming JSON Web Token (JWT).
Some deployment scenarios, such as Open Banking, require the use of a signed assertion as a
method to replace client_id and client_secret. To view the
implementer requirements for client authentication, see https://www.openbanking.org.uk/read-write-apis/security-profile/id1-0-1/.
Security Verify Access OIDC Providers support client authentication to /token
through an incoming JSON Web Token (JWT). Security Verify Access support of client assertions
satisfies RFC 7523. See https://tools.ietf.org/html/rfc7523.
/token with a JWT is different from support for
request JWTs that are presented to /authorize. For /authorize, see
Passing parameters through JWT in a request to /authorize.When an incoming client assertion is detected by the presence of the parameters
client_assertion_type (of a valid value) and client_assertion, the
OAuth delegate invokes a token exchange. This token exchange is to a well-known (predictable) set of
issuer and appliesTo values.
The JWT must contain the following claims:
- iss
- The issuer of the JWT. This value must be that of the security entity that created this JWT. Its presence is validated, but explicit validation of the value must be completed in the STS chain.
- sub
- Subject Identifier. This value must be the
client_idyou want to authenticate. - aud
- Intended audiences for the ID Token. It must be a value that represents this entity, such as the API Protection definition name.
- exp
- Expiration time on or after which the JWT is not accepted for processing.
The parameter nbf, if present, is validated. This parameter is the "not before" claim that identifies the time before which the JWT is not accepted for processing.
You can create a Secure Token Service (STS) chain with modules to handle client assertions through incoming JWTs during authentication. To configure an STS chain that is compatible with incoming client assertions, the chain must ensure:
- No token type is set.
- RequestType of Validate is accepted.
Examples of ISSUER and APPLIESTO fields that handle all
presented client assertions are as follows:
ISSUER="REGEXP:(urn:ietf:params:oauth:client-assertion-type:jwt-bearer:.*)"
APPLIESTO=https://localhost/sps/oauth/oauth20
.* value in
the regexp for the Issuer.) If a particular chain is needed, then use the
issuer:urn:ietf:params:oauth:client-assertion-type:jwt-bearer:myClient
where myClient is the client_id of the interested client. - The
issueris a combination of the assertion type plus the client identifier. - The
appliestois the federation name. For Security Verify Access, the federation name is always:https://localhost/sps/oauth/oauth20
The client configured secret and jwks_uris are included in the
request to the STS through WS-Trust claims. To view how the JWT module supports validation, see
Validate mode.
After the JWT is validated, OAuth expects a Secure Token Service Universal User (STSUU) in return, as follows:
- The
subclaim is populated with theclient_idof the incoming request. - The
audfield is checked against the configured issuer identifier of the API definition.Note: The values ofissandaudmust be validated. This validation can be done through the STS chain configuration, or in a map module in the STS chain, or in the pre-token mapping rule. Validation within the chain is easiest when the values ofissandaudare static.
All the claims in the JWT are mapped into the STSUU attribute list, with the type similar to
urn:ibm:oauth20:client:assertion.
To implement this set of features, you must configure an STS chain with the following modules:
- JWT module in Validate mode >
- An optional JavaScript mapping rule >
- STSUU module in Issue mode
Following is an example of code for retrieving the values:
var sub = stsuu.getAttributeContainer().getAttributeValueByName("sub");
var aud = stsuu.getAttributeContainer().getAttributeValueByName("aud");
var iss = stsuu.getAttributeContainer().getAttributeValueByName("iss");
IDMappingExtUtils.traceString("sub: " + sub + " aud: " + aud + " iss: " + iss);