OIDC Claims customization
You can customize the OIDC claims that contain information about the user and about the authentication event.
The OIDC specification describes standards for creating and processing claims. OpenID defines a
standard set of basic profile Claims. You can use specific scope values to access pre-defined sets
of Claims. You can also request individual Claims by using the claims
request
parameter.
The specification outlines the following structure for defining and handling claims:
- There are about twenty standard claims, such as
name
,picture
,gender
, and so on. - You can use the
scope
parameter to request Claims. There are well defined scopes, each of which translates to a collection of standard claims such asprofile
,email
,phone
, andaddress
. - You can also request claims individually by using the
claims
request parameter. - When an access token exists, claims are returned in
UserInfo
. When there is no access token, claims are returned inID Tokens
. UserInfo
is returned at the/userinfo
endpoint. ID Tokens are returned at either the/authorize
or/token
endpoints, depending on which OIDC flow is executed.- There are additional request parameters that can affect the claims. Examples of these include
max_age
,acr_values
, andclaims_locales
.
OIDC does not perform authentication itself, but relies on an authentication module to
authenticate the user. This means that the OIDC protocol cannot provide claims values, because it
has no knowledge of what user information is available, and how to the data is stored. For example,
perhaps only the user name
information is available, but is stored in LDAP as the
attribute cn
.
As a result, Security Access Manager supports the customization of claims values. For ID Tokens, you can customize claims values through a pre-token mapping rule. For UserInfo, you can customize claims in a post-mapping rule.
In Security Access Manager, when you create a new OIDC Definition, default pre-token and post-token mapping rules are created. These mapping rules contain examples of how the claims can be resolved.
UserInfo endpoint
The OIDC specification recommends the use of the UserInfo endpoint. The UserInfo endpoint is useful, for example, when a Relying Party cannot parse a JWT Token to obtain information about the authenticated user.
Without the use of customization, the /userinfo endpoint contains only the field
sub
. This is the subject identifier for the end-user at the issuer.
The specification mandates to output the claims as much as possible at the /userinfo endpoint, except when an access token is not generated. Also, in some cases the ID Token is generated at both /authorize and /token endpoint. The Security Access Manager will not impose any restriction of which claims must be output to ID Token or User Info. Likewise, there are no restrictions that the same claims must be returned at /authorize and /token. Based on the needs of your deployment, you can choose not to output some claims in certain flows even though the claims are requested.
The /userinfo endpoint is protected by an access token. You can access it by an HTTP GET or POST. See the following links:
- http://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest
- https://tools.ietf.org/html/rfc6750#section-2
An unauth
ACL is attached for this endpoint.
Claims List
Many parameters can contribute to a claims list. For example, parameters specified by a scope are often used to build a list. By parsing the claims parameter, you can also retrieve individual claims and determine which claims are for UserInfo and which claims are for ID Tokens.
Security Access Manager builds a claims list and makes it available in the Security Token Service
Universal User (STSUU) as a list of voluntary and essential claims. This list is produced only for
OIDC requests that have scope openid
against an OIDC-enabled provider.
The processing sequence is:
- The
scope
parameter is processed first, since all claims requested through it are voluntary claims. The specification defines only profile, address, email, and phone scopes as well-defined scopes. These translate into a list of standard claims. However, if the scope contains other scopes that are not well-defined, it is treated as an individual claim. - Next the claims parameter is processed. Either UserInfo or ID Token is processed, depending on the endpoint.
Claim | Type |
Voluntary claims | urn:ibm:names:ITFIM:oidc:claim:voluntary |
Essential claims | urn:ibm:names:ITFIM:oidc:claim:essential |
For example, given a request with scope=“openid phone organization”
and a
claims
parameter that is the described in the following JavaScript Object Notation
(JSON):
{
"userinfo": {
"given_name": {"essential": true},
"email": {"essential": true},
"email_verified": {"essential": true},
"http://example.info/claims/groups": null
},
"id_token": {
"nickname": null,
"auth_time": {"essential": true},
"acr": {"values": ["urn:mace:silver"] }
}
}
At the /authorize or /token endpoint where the ID Token can be generated, the following is available in the STSUU context:
<stsuuser:ContextAttributes>
// from scope: phone and organization
<stsuuser:Attribute name=“organization" type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
<stsuuser:Attribute name="phone_number" type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
<stsuuser:Attribute name="phone_number_verified"
type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
// from id_token claims parameter
<stsuuser:Attribute name="nickname" type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
<stsuuser:Attribute name="auth_time" type="urn:ibm:names:ITFIM:oidc:claim:essential"/>
<stsuuser:Attribute name="acr" type="urn:ibm:names:ITFIM:oidc:claim:voluntary">
<stsuuser:Value>urn:mace:silver</stsuuser:Value>
</stsuuser:Attribute>
</stsuuser:ContextAttributes>
At the /userinfo endpoint, the following is available in the STSUU context:
<stsuuser:ContextAttributes>
// from scope: phone and organization
<stsuuser:Attribute name=“organization" type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
<stsuuser:Attribute name="phone_number" type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
<stsuuser:Attribute name="phone_number_verified"
type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
// from userinfo claims parameter
<stsuuser:Attribute name="given_name" type="urn:ibm:names:ITFIM:oidc:claim:essential"/>
<stsuuser:Attribute name="email" type="urn:ibm:names:ITFIM:oidc:claim:essential"/>
<stsuuser:Attribute name="email_verified"
type="urn:ibm:names:ITFIM:oidc:claim:essential"/>
<stsuuser:Attribute name="http://example.info/claims/groups"
type="urn:ibm:names:ITFIM:oidc:claim:voluntary"/>
</stsuuser:ContextAttributes>
Retrieving Claim Values
You can use the function associate()
and UserLookupHelp to
retrieve claim values. Security Access Manager allows you to also retrieve claim values by using
attribute sources. The Federation support in Security Access Manager includes management of
attribute sources, in the LMI under Advanced Access Control.
You can provide mappings between a specific attribute name and an attribute source, as part of configuring an OIDC Definition. During runtime, this mapping is resolved and made available in the STSUU.
For example, assume the attribute sources in the following table are configured.
Attribute Name | Value | Type |
---|---|---|
CredentialNickName | AZN_CRED_PRINCIPAL_NAME | Credential |
FixedOrganization | www.ibm.com | Fixed |
LDAPMail | LDAP |
Assume also that you have created the following attribute mapping in the OIDC Definition configuration.
Attribute Name | Attribute Source |
---|---|
LDAPMail | |
nickname | CredentialNickName |
organization | FixedOrganization |
Then, during runtime, in the STSUU the following attributes can be found:
<stsuuser:AttributeList>
<stsuuser:Attribute name=“nickname" type="urn:ibm:names:ITFIM:5.1:accessmanager">
<stsuuser:Value>test1</stsuuser:Value>
</stsuuser:Attribute>
<stsuuser:Attribute name=“organization" type="urn:ibm:names:ITFIM:5.1:accessmanager">
<stsuuser:Value>www.ibm.com</stsuuser:Value>
</stsuuser:Attribute>
<stsuuser:Attribute name="email" type="urn:ibm:names:ITFIM:5.1:accessmanager">
<stsuuser:Value>test1@iswga.com</stsuuser:Value>
</stsuuser:Attribute>
</stsuuser:AttributeList>
The resolution of attribute sources during runtime is dependent on the context. The context is the list of attributes that are available in the STSUU at that moment. The following conditions apply:
-
For fixed attribute source, there is no restriction on attribute source resolution.
-
For a credential type attribute source, resolution occurs best at the /authorize endpoint. This is because since the entire authentication information (and credential) is available at that time.
-
For LDAP type attribute source, if you are using a macro for the search filter or baseDN, resolution also depends on the context. The information might be available in STSUU, but in a different context it might be available under a different name. This means it can be difficult to create one LDAP attribute source that fits all contexts.
The common use of a macro is to retrieve information based on the username that is being authenticated. Security Access Manager includes an attribute
oidc_username
which contains the authenticated username in all contexts: whether at /authorize, /token or /userinfo endpoints. For example, you can create a common LDAP Attribute Source, as shown in the following table.Table 4. LDAP Attribute Source example Type LDAP Attribute Name LDAPMail
LDAP Attribute mail
Server Connection TestLDAP
Scope Subtree
Selector uid
Search filter: (uid={oidc_username})
Base DN: dc=iswga
Saving Values or Parameters
Security Access Manager enables you to save values or parameters that are related to the claims at the /authorize endpoint.
For example, some request parameters can be specified at the /authorize endpoint, but the claims
might be produced at the /token or /userinfo endpoint. The claims need to be saved so that they can
be available at the /token or /userinfo endpoint. An example of this is the
claims_locales
request parameter.
Another example is the existence of values, such as credential information, that are available at the /authorize endpoint, but need to be output at the /token or /userinfo endpoint. An example of this is the values that are used in the credential type attribute sources. You can save these values. This overcomes the limitation of the attribute source such that for the credential-type attribute source, the context exists only at the /authorize endpoint, and if the values are not saved, the context is not available at any other endpoint.
You can do this by creating a context attribute in the STSUU of the type
urn:ibm:names:ITFIM:oidc:claim:parameter
for parameter or
urn:ibm:names:ITFIM:oidc:claim:value
for value.
The difference between these two types is that, during runtime, the claim value is put back into
STSUU Attribute List under type urn:ibm:names:ITFIM:5.1:accessmanager
, but the
claim parameter is put in the STSUU context under type
urn:ibm:names:ITFIM:oidc:claim:parameter
.
Note that these saved values or parameters exist as long as the grant exists. When the grant is removed or expires, the saved values and parameters are removed.
For example, we man modify the pre-token mapping rule and add the following code to save the
AZN_CRED_PRINCIPAL_NAME
attribute.
var saveValue = stsuu.getAttributeContainer()
.getAttributeValueByNameAndType("AZN_CRED_PRINCIPAL_NAME",
"urn:ibm:names:ITFIM:5.1:accessmanager");
if (saveValue != null) {
var attro = new com.tivoli.am.fim.trustserver.sts.uuser.Attribute("AZN_CRED_PRINCIPAL_NAME",
"urn:ibm:names:ITFIM:oidc:claim:value", saveValue);
stsuu.getContextAttributes().setAttribute(attro);
}
By doing this, the CredentialNickName
attribute source (as shown in the example
earlier in this article) can be resolved in the /token or /userinfo endpoint.
Customizing claims
Security Access Manager provides, in pre-token and post-token mapping rule, examples of how to customize the claims.
For ID Tokens, customization is done in a pre-token mapping rule. You must enable the sample by
setting the customize_id_token
variable to true
. For UserInfo,
customization is done in a post-token mapping rule.
For the example, the algorithm used is the same. The first step is to retrieve the claim list. You might want to process essential claims and voluntary claims separately.
To resolve claims, the produceClaim()
method is called. If an expected value, as
specified by the claim, is found, use it. Next, try to find an attribute that has been resolved
using Attribute Source mapping, and has the same name as the claim. Next, if still there is no
value, for essential claims, you can set some value or optionally throw an STS exception. Note,
however, that the OIDC specification does not recommend throwing an error even if an essential claim
cannot be fulfilled.
For the final step, if the claim value exists, it is put into the STSUU. The type must be set
correctly, in order to included as part of ID Token or UserInfo. For ID Token, the type must be
urn:ibm:jwt:claim
. For UserInfo, the type must be
urn:ibm:names:ITFIM:oauth:response:attribute
.
Special parameter for UserInfo
You can customize UserInfo by using a special attribute. You can create an attribute in the STSUU
Context, with name userinfo
and type
urn:ibm:names:ITFIM:oauth:rule:userinfo
, with the value as a JSON string.
The purpose of this special parameter is to allow you to provide a complex value for UserInfo, in
situations where the limitations of the STSUU structure prevent support for the value. For example,
the following JSON defines an address
that consists of two parts:
{"firstname":"John",
"lastname":"Doe",
"address":{
"zipcode":34234
"city":"Newark"
}
}
The JSON string provided in this parameter serves as the base JSON structure, and is added with other customization attributes, if they exist, to the output of the /userinfo endpoint.
Another use of the special parameter is when you want to generate UserInfo in JWT format. By default, the Security Access Manager implementation produces UserInfo in JSON format. If you need to produce UserInfo in JWT format, there is an example in the post-mapping rule.
To use the example in the post-mapping rule, complete the following steps:
- Create an STS chain that includes the modules in the table below.
Table 5. Chain modules for JWT format Module Mode Default STSUU Module Instance Validate Default Jwt Module Issue Default STSUU Module Instance Issue For more information on creating STS templates and chains, see Managing trust chains.
- In the post mapping-rule, set
produce_jwt_userinfo
totrue
:var produce_jwt_userinfo = true;