OpenID Connect claims
1. Identity provider claims
Client applications that rely on a identity provider (IdP) to sign in a user also often have the need to obtain specific information about her. For example:
- Name, picture, locale – to personalise the application UI;
- Email – to dispatch notifications;
- Address – for an online shop to deliver a package;
- Roles, department – for a business application, in order determine what level of access to give the user.
The identity provider (IdP) fulfils this job by making a set of user details, or attributes, available to client applications. In OpenID Connect these are called claims.
2. Claim types
2.1 Standard claims
OpenID Connect defines a set of standard names for claims that are commonly used across applications. An IdP should use standard claims whenever possible, instead of defining its own.
Category | Claim names |
---|---|
email, email_verified | |
Telephone number | phone_number, phone_number_verified |
Profile | name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, updated_at |
Address | address |
2.2 Custom claims
OpenID Connect providers can also define their own additional claims. Enterprises may for instance define claims such as employee role, manager, and department. The names of any additional claims should be prefixed by a URI to create a safe namespace and prevent collisions, especially if the IdP is federating claims from external sources.
https://claims.idp.mycompany.com/role
3. Claims format and localisation
The IdP must present the claims in JSON format.
{
"sub" : "alice",
"email" : "alice@wonderland.net",
"email_verified" : true,
"name" : "Alice Adams",
"given_name" : "Alice",
"family_name" : "Adams",
"phone_number" : "+359 (99) 100200305",
"profile" : "https://c2id.com/users/alice",
"https://claims.idp.mycompany.com/role" : [ "sys-auditor", "sys-admin" ]
}
The claims can be localised, by affixing a language tag to the claim name.
{
"sub" : "peter",
"given_name#en" : "Peter",
"given_name#bg" : "Петър"
}
4. Claims delivery
There are two ways for a client application to receive released claims about the logged in user from the OpenID Connect provider – at its UserInfo endpoint or included in the ID token.
4.1 UserInfo endpoint
By making a request to the userinfo endpoint of the IdP with a valid OAuth 2.0 access token that was previously issued to the client for the given user.
Example UserInfo request to get the claims for a logged-in user:
GET /userinfo HTTP/1.1
Host: idp.mycompany.com
Authorization: Bearer Gp7b5hiURKpWzEXgMJP38EnYimgxlBC1PpS2zGXUqe
Example UserInfo response returning the consented claims as a JSON object:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub" : "alice",
"email" : "alice@wonderland.net",
"email_verified" : true,
"name" : "Alice Adams"
}
The client application can also register to receive the claims at the UserInfo endpoint as a signed and optionally encrypted JWT.
4.2 ID token
The claims can also be included alongside those that form the ID token.
{
"sub" : "alice",
"iss" : "https://idp.mycompany.com",
"aud" : "client-12345",
"iat" : 1311280970,
"exp" : 1311281970
"email" : "alice@wonderland.net",
"email_verified" : true,
"name" : "Alice Adams"
}
5. Requesting claims
The OpenID authentication request to get an ID token from the IdP for the end-user can also specify which claims the client application is interested in.
The preferred method of claims delivery – at the UserInfo endpoint or with the ID token, is determined from the request.
Bear in mind that the release of the claims is a matter of availability and consent, and the IdP or the end-user may choose to provide a subset or even none of the claims that the client application requested.
5.1 Requesting claims via the scope parameter
The easiest way for a client to request claims is via the scope parameter.
OpenID Connect defines a several standard scope values which map to sets of related claims:
Scope value | Associated claims |
---|---|
email, email_verified | |
phone | phone_number, phone_number_verified |
profile | name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, updated_at |
address | address |
For example, the following authentication request indicates that the client wishes to access the email and email_verified claims of the end-user (which map from the email scope value):
https://idp.mycompany.com/login?response_type=code
&scope=openid%20email
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
The Connect2id server IdPs to specify their own custom scope value to claim names mappings.
For all response_types that result in a access token being issued the
consented claims will be made available for retrieval at the UserInfo endpoint.
Only for response_type=id_token
which results in the issue of an ID token and
no access token, will the claims be included in the ID token.
5.2 Requesting claims via the claims parameter
Client applications can alternatively request claims via the optional claims parameter which allows for fine grained control of the following:
-
Setting the exact names of the requested claims;
-
Which claims should be delivered at the UserInfo endpoint and which in the ID token (it’s possible to deliver the same claim via both methods);
-
Preferred locales / languages for the requested claims by affixing a language tag;
-
Allows the client to indicate which claims are essential for the application’s operation (the default assumption is that all claims are voluntary, i.e. non-essential).
The claims request parameter is represented by a simple JSON object that has two members – userinfo and id_token, which content indicates which claims to return at the UserInfo endpoint and which with the ID token, together with indication whether the claim is voluntary (default) or essential.
To request the email and email_verified claims in the ID token, assuming they are voluntary:
{
"id_token" : {
"email" : null,
"email_verified" : null
}
}
To request the same claims also at the UserInfo endpoint, together with name:
{
"id_token" : {
"email" : null,
"email_verified" : null
},
"userinfo" {
"email" : null,
"email_verified" : null,
"name" : null
}
}
To mark the above claims as essential:
{
"id_token" : {
"email" : { "essential" : true },
"email_verified" : { "essential" : true },
},
"userinfo" {
"email" : { "essential" : true },
"email_verified" : { "essential" : true },
"name" : { "essential" : true },
}
}
Note that the claims parameter must be URL encoded before adding it to the authentication request URL, to make sure all special characters are properly escaped. If you’re using our OpenID Connect / OAuth 2.0 SDK this will be done automatically for you.
6. Consent
How the IdP determines which claims to release is and which not is up to its policy.
The consent for a given claim can be explicit – meaning the end-user must approve its release to the client application, or implicit – meaning that decision is made automatically by the IdP, for example by consulting a policy rule. The consent can also be a combination of both methods.
The Connect2id server supports both consent methods – explicit as well as
implicit. When it’s determined which claims should be released for the present
end-user to the given client application the handler just sets the claims
field of the consent object.
{
"scope" : [ "openid", "email" ],
"claims" : [ "email", "email_verified" ]
}
If the consented claims can be found in the configured database(s) or other sources, they will be delivered to the client according to the requested method (UserInfo or ID token).
7. Non-requested claims
The Connect2id server can also release claims that are not requested by the
client application. Simply put their names in the claims
field of the
consent object when the request is
being processed.
For example, to release the claim https://claims.idp.mycompany.com/role which wasn’t requested by the client:
{
"scope" : [ "openid", "email" ],
"claims" : [ "email", "email_verified", "https://claims.idp.mycompany.com/role" ]
}
The non-requested claims will be delivered according to the response_type set
by the client, i.e. at the UserInfo endpoint, unless response_type=id_token
(no access token is issued). To return the claim in the ID token when the
default delivery resolves to UserInfo, prefix the claim name with id_token:
when putting it into the consented claims
field:
{
"scope" : [ "openid", "email" ],
"claims" : [ "email", "email_verified", "id_token:https://claims.idp.mycompany.com/role" ]
}
You can also have the non-requested claim delivered with both methods:
{
"scope" : [ "openid", "email" ],
"claims" : [ "email",
"email_verified",
"https://claims.idp.mycompany.com/role",
"id_token:https://claims.idp.mycompany.com/role" ]
}
7. Respect privacy
If you’re an application developer, respect the user’s privacy and keep the requested claims down to the minimal required. You can always ask for additional claims later, when the application needs them. This will increase your chances of user conversion and will also ensure compliance with privacy laws.