Claims
IdentityServer emits claims about users and clients into tokens. You are in full control of which claims you want to emit, in which situations you want to emit those claims, and where to retrieve those claims from.
User Claims
Section titled “User Claims”User claims can be emitted in both identity and access tokens and in the userinfo endpoint. The central extensibility point to implement to emit claims is called the profile service. The profile service is responsible for both gathering claim data and deciding which claims should be emitted.
Whenever IdentityServer needs the claims for a user, it invokes the registered profile service with a context that presents detailed information about the current request, including
- the client that is making the request
- the identity of the user
- the type of the request (access token, id token, or userinfo)
- the requested claim types, which are the claims types associated with requested scopes and resources
Strategies For Emitting Claims
Section titled “Strategies For Emitting Claims”You can use different strategies to determine which claims to emit based on the information in the profile context.
- emit claims based on the requested claim types
- emit claims based on user or client identity
- always emit certain claims
Emit Claims Based On The Client’s Request
Section titled “Emit Claims Based On The Client’s Request”You can filter the claims you emit to only include the claim types requested by the client. If your client requires consent, this will also give end users the opportunity to approve or deny sharing those claims with the client.
Clients can request claims in several ways:
- Requesting an IdentityResource by including the scope parameter
for the
IdentityResource
requests the claims associated with theIdentityResource
in itsUserClaims
collection. - Requesting an ApiScope by including the scope parameter for
the
ApiScope
requests the claims associated with theApiScope
in itsUserClaims
collection. - Requesting an ApiResource by including the resource
indicator parameter for the
ApiResource
requests the claims associated with theApiResource
in itsUserClaims
collection.
The RequestedClaimTypes
property of the ProfileDataRequestContext
contains the collection of claims requested by the
client.
If your profile service extends the DefaultProfileService
, you can use its AddRequestedClaims
method to add only
requested and approved claims. The intent is that your profile service can retrieve claim data and then filter that
claim data based on what was requested by the client. For example:
public class SampleProfileService : DefaultProfileService{ public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context) { var claims = await GetClaimsAsync(context);
context.AddRequestedClaims(claims); }
private async Task<List<Claim>> GetClaimsAsync(ProfileDataRequestContext context) { // Your implementation that retrieves claims goes here }}
Always Emit Claims
Section titled “Always Emit Claims”We generally recommend emitting claims based on the requested claim types, as that respects the scopes and resources
requested by the client and gives the end user an opportunity to consent to this sharing of information. However, if you
have claims that don’t need to follow such rules, such as claims that are an integral part of the user’s identity and
that are needed in most scenarios, they can be added by directly updating the context.IssuedClaims
collection. For
example:
public class SampleProfileService : DefaultProfileService{ public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context) { var claims = await GetClaimsAsync(context); context.IssuedClaims.AddRange(claims); }
private async Task<Claim> GetClaimsAsync(ProfileDataRequestContext context) { // Your implementation that retrieves claims goes here }}
Emit Claims Based On The User Or Client Identity
Section titled “Emit Claims Based On The User Or Client Identity”Finally, you might have claims that are only appropriate for certain users or clients. Your ProfileService
can add
whatever filtering or logic that you like.
The Subject Of The ProfileDataRequestContext
Section titled “The Subject Of The ProfileDataRequestContext”When the profile service is invoked to add claims to tokens, the Subject
property on the ProfileDataRequestContext
contains the principal that was issued during user sign-in. Typically, the profile service will source some claims from
the Subject
and others from databases or other data sources.
When the profile service is called for requests to
the userinfo endpoint, the Subject
property will not contain the
principal issued during user sign-in, since userinfo calls don’t happen as part of a session. Instead, the Subject
property will contain a claims principal populated with the claims in the access token used to authorize the userinfo
call. You can check the caller of the profile service by querying the Caller
property on the context.
Client Claims
Section titled “Client Claims”Client claims are a set of pre-defined claims that are emitted in access tokens. They are defined on a per-client basis, meaning that each client can have its own unique set of client claims. The following shows an example of a client that is associated with a certain customer in your system:
var client = new Client{ ClientId = "client",
// rest omitted
Claims = { new ClientClaim("customer_id", "123") }};
To avoid accidental collision with user claims, client claims are prefixed with client_
. For example, the above
ClientClaim
would be emitted as the client_customer_id
claim type in access tokens. You can change or remove this
prefix by setting the ClientClaimsPrefix
on the client definition.
Setting Client Claims Dynamically
Section titled “Setting Client Claims Dynamically”If you want to set client claims dynamically, you could either do that at client load time (via a client store implementation), or using a custom token request validator.
Claim Serialization
Section titled “Claim Serialization”Claim values are serialized based on the ClaimValueType
of the claim. Claims that don’t specify a ClaimValueType are
simply serialized as strings. Claims that specify a ClaimValueType of System.Security.Claims.ClaimValueTypes.Integer
,
System.Security.Claims.ClaimValueTypes.Integer32
, System.Security.Claims.ClaimValueTypes.Integer64
,
System.Security.Claims.ClaimValueTypes.Double
, or System.Security.Claims.ClaimValueTypes.Boolean
are parsed as the
corresponding type, while those that specify IdentityServerConstants.ClaimValueTypes.Json
are serialized to JSON using
System.Text.Json
.