What are User Claims in IdentityServer4 API Resources vs. API Scopes

A resource is a concept that can be divided into logical parts (scopes) which may be implementated in various ways. Either way, though this may not be very obvious from the documentation, for IdentityServer one resource has at least one scope.

In order to allow a client to access a resource, the client must be configured which scopes are allowed for that client. In the samples the name of the scope is equal to the name of the resource, but in reality a resource has probably multiple scopes. Please note that a client that is allowed to use one scope only, can access the entire resource (audience), unless the resource (api) filters access, based on the allowed scope (scopes are part of the access token as scope claims).

One feature of IdentityServer is that it is a token provider, e.g. for access tokens and identity tokens.

To start with the last one, there are two types of identity tokens. There is one 'minimal' identity token (contains the 'sub' claim only) that is issued only when requested along with an access token. And there is a 'full' identity token that can be requested by a client at the UserInfo endpoint.

For IdentityServer the user claims are a resource (of identity information). As a side note, the user should be asked for consent before using this information because the user owns this information.

Not all user claims should make it to the Identity Token that is requested at the UserInfo endpoint. In order to determine which claims should, IdentityServer looks at the Identity~ tables. Based on these tables a RequestedClaims collection is available for the UserInfo context that is used to filter the user claims resource.

In other words, when a client is configured to request the 'openid' scope, then only the 'sub' claim is included, adding the 'profile' scope will include the underlying profile claims (if available in the UserClaims table), and configuring the 'email' scope will add the email as well to the Identity Token.

For the access token there is a similar mechanism. Based on the ApiClaims and ApiScopeClaims table a RequestedClaims collection is available for the Authorization context. Take a look at my answer here for more information.

Suppose you want to add the 'name' claim to the access token, then add it to one of the tables. Take a look at my answer here or in fact, the entire thread, for additional information.

Though it is possible with IdentityServer to add all sorts of claims to the access token, you should wonder whether this is the right approach, as explained in this post.

The problem with access token claims is that these claims are used for user authorization. But user claims are typically not meant for user authorization. And you don't want to end up with one super access token, containing all claims.

Taking one step back, IdentityServer is there to configure resource protection and client authorization. A client can connect to a resource (scope) but it's the user that is authorized to access the information: requests from a client are always 'on behalf of the user'. That's why the 'sub' claim is always (in an interactive flow) part of the access token. In addition IdentityServer can be extended to handle user authentication. But, though it is possible in the current design, user authorization is not (or at least no longer) the concern of IdentityServer.

The creators of IdentityServer have been thinking about user authorization in the past and came up with a seperate service for this: the PolicyServer. Taking the authorization claims out of IdentityServer and out of the access token.

So, in order to answer your question, the different tables are used to configure resources, scopes, clients, and filters that are used to build tokens. User claims tell something about the user (identity) and are not in place in an access token.

For user authorization I can recommend a PolicyServer server like implementation, combined with resource-based authorization.

A short summary of the tables:

  • AspNetUserClaims - resource of user information

  • ApiResources - the name of the resource

  • ApiScopes - one-to-many scopes that are part of a resource

  • IdentityResources - actually the scope of identity (e.g. openid profile)

  • IdentityClaims - filters AspNetUserClaims for the identity token

  • ApiClaims - filters AspNetUserClaims for the access token, regardless which scope is requested

  • ApiScopeClaims - filters AspNetUserClaims for the access token, depends on the requested scope

  • ClientClaims - claims that are included for the specific client

  • ClientScopes - the allowed scopes for a client

A client requests scopes. If scopes are omitted then (by specification) all allowed scopes are considered as requested.

An api is part of the resource (audience). Finer grained client authorization (based on scope) is required when a resource has multiple scopes.

User authorization is there to determine what a user is allowed to do: a client can connect to the api, is filtered by scope (e.g. calendar) and the user is authorized to read but not write events.

Though calendar.write and calendar.read can be scopes, it has nothing to do with user authorization. The user can be authorized to read and write, but since the client may be limited (e.g. calendar.read only) the user may have to use seperate clients in order to connect to the resource, e.g. a calendar app has both, an email app calendar.read only.

ApiResource can contains many scopes(orders,discounts,accounting ...). for example you need a token to access profile information of GitHub, not repositories or etc. in this case GitHub is an ApiResource and contains profile scope.

when user sends a request for token just specify some scopes (not ApiResource), then IdentityServer detects which ApiResources user want to access (from requested scopes).

UserClaims in ApiResource: When you specify UserClaims in an ApiResource, when user request for a token to access that ApiResource, those UserClaims will be in the token.

There is no any UserClaims for scopes.