How claim type works in ASP NET Core and ABP Framework
The Claim Type
A web application may use one or more authentication schemes to obtain the current user's information, such as Cookies
, JwtBearer
, OpenID Connect
, Google
etc.
After authentication, we get a set of claims that can be issued using a trusted identity provider. A claim is a type/name-value pair representing the subject. The type property provides the semantic content of the claim, that is, it states what the claim is about.
The ICurrentUser
service of the ABP Framework provides a convenient way to access the current user's information from the claims.
The claim type is the key to getting the correct value of the current user, and we have a static AbpClaimTypes
class that defines the names of the standard claims in the ABP Framework:
public static class AbpClaimTypes
{
public static string UserId { get; set; } = ClaimTypes.NameIdentifier;
public static string UserName { get; set; } = ClaimTypes.Name;
public static string Role { get; set; } = ClaimTypes.Role;
public static string Email { get; set; } = ClaimTypes.Email;
//...
}
As you can see, the default claim type of AbpClaimTypes
comes from the System.Security.Claims.ClaimTypes
class, which is the recommended practice in NET.
Claim type in different authentication schemes
We usually see two types of claim types in our daily development. One of them is the System.Security.Claims.ClaimTypes
and the other one is the OpenId Connect
standard claims.
ASP NET Core Identity
There is a ClaimsIdentityOptions
property in the IdentityOptions
, which can be used to configure the claim type:
Property | Description |
---|---|
EmailClaimType | Gets or sets the ClaimType used for the user email claim. Defaults to Email. |
RoleClaimType | Gets or sets the ClaimType used for a Role claim. Defaults to Role. |
SecurityStampClaimType | Gets or sets the ClaimType used for the security stamp claim. Defaults to "AspNet.Identity.SecurityStamp". |
UserIdClaimType | Gets or sets the ClaimType used for the user identifier claim. Defaults to NameIdentifier. |
UserNameClaimType | Gets or sets the ClaimType used for the user name claim. Defaults to Name. |
- The Identity creates a
ClaimsIdentity
object with the claim type that you have configured in theClaimsIdentityOptions
class. - The ABP Framework configures it based on
AbpClaimTypes,
so usually you don't need to worry about it.
JwtBearer/OpenID Connect Client
The JwtBearer/OpenID Connect
gets claims from id_token
or fetches user information from the AuthServer
, and then maps/adds it to the current ClaimsIdentity
.
To map the standard claim type to the System.Security.Claims.ClaimTypes
via azure-activedirectory-identitymodel-extensions-for-dotnet library by default, which is maintained by the Microsoft team:
Dictionary<string, string> ClaimTypeMapping = new Dictionary<string, string>
{
{ "actort", ClaimTypes.Actor },
{ "birthdate", ClaimTypes.DateOfBirth },
{ "email", ClaimTypes.Email },
{ "family_name", ClaimTypes.Surname },
{ "gender", ClaimTypes.Gender },
{ "given_name", ClaimTypes.GivenName },
{ "nameid", ClaimTypes.NameIdentifier },
{ "sub", ClaimTypes.NameIdentifier },
{ "website", ClaimTypes.Webpage },
{ "unique_name", ClaimTypes.Name },
{ "oid", "http://schemas.microsoft.com/identity/claims/objectidentifier" },
{ "scp", "http://schemas.microsoft.com/identity/claims/scope" },
{ "tid", "http://schemas.microsoft.com/identity/claims/tenantid" },
{ "acr", "http://schemas.microsoft.com/claims/authnclassreference" },
{ "adfs1email", "http://schemas.xmlsoap.org/claims/EmailAddress" },
{ "adfs1upn", "http://schemas.xmlsoap.org/claims/UPN" },
{ "amr", "http://schemas.microsoft.com/claims/authnmethodsreferences" },
{ "authmethod", ClaimTypes.AuthenticationMethod },
{ "certapppolicy", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/applicationpolicy" },
{ "certauthoritykeyidentifier", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/authoritykeyidentifier" },
{ "certbasicconstraints", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/basicconstraints" },
{ "certeku", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/eku" },
{ "certissuer", "http://schemas.microsoft.com/2012/12/certificatecontext/field/issuer" },
{ "certissuername", "http://schemas.microsoft.com/2012/12/certificatecontext/field/issuername" },
{ "certkeyusage", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/keyusage" },
{ "certnotafter", "http://schemas.microsoft.com/2012/12/certificatecontext/field/notafter" },
{ "certnotbefore", "http://schemas.microsoft.com/2012/12/certificatecontext/field/notbefore" },
{ "certpolicy", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/certificatepolicy" },
{ "certpublickey", ClaimTypes.Rsa },
{ "certrawdata", "http://schemas.microsoft.com/2012/12/certificatecontext/field/rawdata" },
{ "certserialnumber", ClaimTypes.SerialNumber },
{ "certsignaturealgorithm", "http://schemas.microsoft.com/2012/12/certificatecontext/field/signaturealgorithm" },
{ "certsubject", "http://schemas.microsoft.com/2012/12/certificatecontext/field/subject" },
{ "certsubjectaltname", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/san" },
{ "certsubjectkeyidentifier", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/subjectkeyidentifier" },
{ "certsubjectname", "http://schemas.microsoft.com/2012/12/certificatecontext/field/subjectname" },
{ "certtemplateinformation", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/certificatetemplateinformation" },
{ "certtemplatename", "http://schemas.microsoft.com/2012/12/certificatecontext/extension/certificatetemplatename" },
{ "certthumbprint", ClaimTypes.Thumbprint },
{ "certx509version", "http://schemas.microsoft.com/2012/12/certificatecontext/field/x509version" },
{ "clientapplication", "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application" },
{ "clientip", "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-ip" },
{ "clientuseragent", "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent" },
{ "commonname", "http://schemas.xmlsoap.org/claims/CommonName" },
{ "denyonlyprimarygroupsid", ClaimTypes.DenyOnlyPrimaryGroupSid },
{ "denyonlyprimarysid", ClaimTypes.DenyOnlyPrimarySid },
{ "denyonlysid", ClaimTypes.DenyOnlySid },
{ "devicedispname", "http://schemas.microsoft.com/2012/01/devicecontext/claims/displayname" },
{ "deviceid", "http://schemas.microsoft.com/2012/01/devicecontext/claims/identifier" },
{ "deviceismanaged", "http://schemas.microsoft.com/2012/01/devicecontext/claims/ismanaged" },
{ "deviceostype", "http://schemas.microsoft.com/2012/01/devicecontext/claims/ostype" },
{ "deviceosver", "http://schemas.microsoft.com/2012/01/devicecontext/claims/osversion" },
{ "deviceowner", "http://schemas.microsoft.com/2012/01/devicecontext/claims/userowner" },
{ "deviceregid", "http://schemas.microsoft.com/2012/01/devicecontext/claims/registrationid" },
{ "endpointpath", "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path" },
{ "forwardedclientip", "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip" },
{ "group", "http://schemas.xmlsoap.org/claims/Group" },
{ "groupsid", ClaimTypes.GroupSid },
{ "idp", "http://schemas.microsoft.com/identity/claims/identityprovider" },
{ "insidecorporatenetwork", "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork" },
{ "isregistereduser", "http://schemas.microsoft.com/2012/01/devicecontext/claims/isregistereduser" },
{ "ppid", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" },
{ "primarygroupsid", ClaimTypes.PrimaryGroupSid },
{ "primarysid", ClaimTypes.PrimarySid },
{ "proxy", "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy" },
{ "pwdchgurl", "http://schemas.microsoft.com/ws/2012/01/passwordchangeurl" },
{ "pwdexpdays", "http://schemas.microsoft.com/ws/2012/01/passwordexpirationdays" },
{ "pwdexptime", "http://schemas.microsoft.com/ws/2012/01/passwordexpirationtime" },
{ "relyingpartytrustid", "http://schemas.microsoft.com/2012/01/requestcontext/claims/relyingpartytrustid" },
{ "role", ClaimTypes.Role },
{ "roles", ClaimTypes.Role },
{ "upn", ClaimTypes.Upn },
{ "winaccountname", ClaimTypes.WindowsAccountName },
};
Disable JwtBearer/OpenID Connect Client Claim Type Mapping
To turn off the claim type mapping, you can set the MapInboundClaims
property of JwtBearerOptions
or OpenIdConnectOptions
to false
. Then, you can get the original claim types from the token(access_token
or id_token
):
JWT Example:
{
"iss": "https://localhost:44305/",
"exp": 1714466127,
"iat": 1714466127,
"aud": "MyProjectName",
"scope": "MyProjectName offline_access",
"sub": "ed7f5cfd-7311-0402-245c-3a123ff787f9",
"unique_name": "admin",
"preferred_username": "admin",
"given_name": "admin",
"role": "admin",
"email": "admin@abp.io",
"email_verified": "False",
"phone_number_verified": "False",
}
OAuth2(Google, Facebook, Twitter, Microsoft) Extenal Login Client
The OAuth2 handler
fetchs a JSON containing user information from the OAuth2
server. The third-party provider issues the claim type based on their standard server and then maps/adds it to the current ClaimsIdentity
. The ASP NET Core provides some built-in claim-type mappings for different providers as can be seen below examples:
Example: The ClaimActions
property of the GoogleOptions
maps the Google's claim types to System.Security.Claims.ClaimTypes
:
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id"); // v2
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub"); // v3
ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name");
ClaimActions.MapJsonKey(ClaimTypes.Surname, "family_name");
ClaimActions.MapJsonKey("urn:google:profile", "link");
ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
Example: The ClaimActions
property of the FacebookOptions
maps the Facebook's claim types to System.Security.Claims.ClaimTypes
:
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
ClaimActions.MapJsonSubKey("urn:facebook:age_range_min", "age_range", "min");
ClaimActions.MapJsonSubKey("urn:facebook:age_range_max", "age_range", "max");
ClaimActions.MapJsonKey(ClaimTypes.DateOfBirth, "birthday");
ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
ClaimActions.MapJsonKey(ClaimTypes.GivenName, "first_name");
ClaimActions.MapJsonKey("urn:facebook:middle_name", "middle_name");
ClaimActions.MapJsonKey(ClaimTypes.Surname, "last_name");
ClaimActions.MapJsonKey(ClaimTypes.Gender, "gender");
ClaimActions.MapJsonKey("urn:facebook:link", "link");
ClaimActions.MapJsonSubKey("urn:facebook:location", "location", "name");
ClaimActions.MapJsonKey(ClaimTypes.Locality, "locale");
ClaimActions.MapJsonKey("urn:facebook:timezone", "timezone");
OpenIddict AuthServer
The OpenIddict
uses the standard claims as the claim type of the id_token
or access_token
and UserInfo
endpoint response, etc.
- For JWT token, it also uses the azure-activedirectory-identitymodel-extensions-for-dotnet to get the claims from the
id_token
oraccess_token
. - For reference token, it gets the claims from the
database
.
Summary
Once you find the claims you received do not meet your expectations, follow the instructions above to troubleshoot the problem.
This article can help you understand the claim type in the ABP Framework and ASP NET Core.
Comments
No one has commented yet, be the first to comment!