Browse Source

How claim type works in ASP NET Core and ABP Framework.

Resolve #19299
pull/19735/head
maliming 2 years ago
parent
commit
16a7b4b916
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 199
      docs/en/Community-Articles/2024-05-01-How-ABP-get-current-user/POST.md

199
docs/en/Community-Articles/2024-05-01-How-ABP-get-current-user/POST.md

@ -0,0 +1,199 @@
# 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 will 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`](https://docs.abp.io/en/abp/latest/CurrentUser) 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.
```cs
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`](https://learn.microsoft.com/en-us/dotnet/api/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 is the [`System.Security.Claims.ClaimTypes`](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes) and the other one is the `OpenId Connect` [standard claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)
### OpenIddict AuthServer
The `OpenIddict` will use the [standard claims](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) as the claim type of the `id_token` or `access_token` and `UserInfo` endpoint response.
### ASP NET Core Identity
There is a [`ClaimsIdentityOptions`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.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 will create a `ClaimsIdentity` object with the claim type that you have configured in the `ClaimsIdentityOptions` class.
The ABP framework will configure it based on `AbpClaimTypes,` so you shouldn't usually worry about it.
### JwtBearer/OpenID Connect Client
The `JwtBearer/OpenID Connect` will get claims from `id_token` or fetch user information from the `AuthServer`, and then map/add it to the current `ClaimsIdentity`.
To map the [standard claim](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) type to the [`System.Security.Claims.ClaimTypes`](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes) via [azure-activedirectory-identitymodel-extensions-for-dotnet](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) library by default, which is maintained by the Microsoft team.
```cs
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:
```json
{
"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` will fetch a JSON containing user information from the `OAuth2` server. The third-party provider will issue the claim type based on their standard server and then map/add it to the current `ClaimsIdentity`.
The ASP NET Core built-in some claim type mapping for different providers.
Example: The `ClaimActions` of `GoogleOptions` will map the Google's claim types to [`System.Security.Claims.ClaimTypes`](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes)
```cs
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` of `FacebookOptions` will map the Facebook's claim types to [`System.Security.Claims.ClaimTypes`](https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes)
```cs
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");
```
## 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.
Loading…
Cancel
Save