OpenID Connect claims
1. Identity provider claims
Client applications that rely on a identity provider (IdP) to sign in a user may also
- Name, picture, locale – to personalise the application UI;
- Email – to send notifications;
- Address – for an online shop to deliver a package;
- Roles, department – for an enterprise application.
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.
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.example.com/role
An IdP should use standard claims whenever possible, instead of defining its own.
3. Claims format and localisation
The IdP presents 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" : "+35999100305",
"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" : "alice",
"given_name#en" : "Alice",
"given_name#bg" : "Алис"
}
4. Claims delivery
There are two ways for a client application to receive released claims about the logged in user from an 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 Connect2id server with a valid OAuth 2.0 access token that was issued to the client for the user.
Example UserInfo request to retrieve the claims for a logged-in user:
GET /userinfo HTTP/1.1
Host: idp.example.com
Authorization: Bearer Gp7b5hiURKpWzEXgMJP38EnYimgxlBC1PpS2zGXUqe
Example UserInfo response returning the consented claims in 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 can also be registered to receive the claims at the UserInfo endpoint as a signed and optionally encrypted JWT.
4.2 ID token
The alternative delivery is to include the claims in the ID token.
Example ID token where the email, email_verified and name claims are included alongside the standard ID token claims:
{
"sub" : "alice",
"iss" : "https://idp.example.com",
"aud" : "123",
"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 the client wishes to access the email and email_verified claims of the end-user (which map from the email scope value):
https://idp.example.com/login?
scope=openid%20email
&response_type=code
&client_id=123
&state=ei1JieD8geiy7Yau
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
The Connect2id server enables an IdP to specify its own additional custom scope value to claim names mapping.
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:
-
Requesting individual claims;
-
Which claims to request for delivery 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 value must be URL encoded before including it in the authentication request, 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.
Example JSON object for the claims request parameter, before the URL encoding:
{
"id_token" : {
"email" : null,
"email_verified" : null
}
}
After applying URL encoding to the JSON text:
%7B%22id_token%22%3A%7B%22email%22%3Anull%2C%22email_verified%22%3Anull%7D%7D
An OpenID authentication request with the above claims parameter:
https://idp.example.com?
scope=openid
&response_type=code
&client_id=123
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&state=ei1JieD8geiy7Yau
&nonce=ohNgieph5FooS7sh
&claims=%7B%22id_token%22%3A%7B%22email%22%3Anull%2C%22email_verified%22%3Anull%7D%7D
6. Consent
How the IdP determines which claims to release 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. Releasing non-requested claims
The Connect2id server can also release claims which the client application didn’t request with the scope and / or claims parameters. This can be useful when the IdP has a contract for its users to automatically release selected claims to registered clients.
There are two ways to trigger this - in the consent and automatically via a special claims field in the user session.
7.1 Specifying non-requested claims for release at consent time
This can be done at consent time, by simply including the names of the
additional claims for release in the claims
field of the consent
object.
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,
i.e. at the UserInfo endpoint, unless the client made a
request with response_type=id_token
(where no access token is issued). To
release the claim in the ID token when the
default delivery resolves to UserInfo, prefix the claim name with id_token:
,
like this:
{
"scope" : [ "openid", "email" ],
"claims" : [ "email", "email_verified", "id_token:https://claims.idp.mycompany.com/role" ]
}
A non-requested claim can be also 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.2 Feeding claims from the user session into the ID token
The Connect2id server offers the option to automatically feed claims found in the subject session into the ID token.
This behaviour is normally disabled. To enable it set the op.authz.feedSubjectSessionClaimsIntoIDToken configuration property:
op.authz.feedSubjectSessionClaimsIntoIDToken=true
The claims to feed into the ID token will be taken from the optional claims
field of the subject session. The login handler can set the claims
field
when the user session gets
created.
Example:
{
"sub" : "alice",
"claims" : { "https://claims.idp.mycompany.com/role" : [ "admin", "audit" ] }
}
The claims
field can also be set with a dedicated PUT
call to the session store
web API.
8. Respect user 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.