Client authentication to /token through an incoming JSON Web Token
Security Access Manager 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 Access Manager OIDC Providers support client authentication to /token
through an incoming JSON Web Token (JWT). Security Access Manager 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_id
you 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
issuer
is a combination of the assertion type plus the client identifier. - The
appliesto
is the federation name. For Security Access Manager, 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
sub
claim is populated with theclient_id
of the incoming request. - The
aud
field is checked against the configured issuer identifier of the API definition.Note: The values ofiss
andaud
must 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 ofiss
andaud
are 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);