title | author | description | monikerRange | ms.author | ms.custom | ms.date | uid |
---|---|---|---|---|---|---|---|
Persist additional claims and tokens from external providers in ASP.NET Core |
rick-anderson |
Learn how to establish additional claims and tokens from external providers. |
>= aspnetcore-2.1 |
riande |
mvc |
02/18/2021 |
security/authentication/social/additional-claims |
:::moniker range=">= aspnetcore-6.0"
An ASP.NET Core app can establish additional claims and tokens from external authentication providers, such as Facebook, Google, Microsoft, and Twitter. Each provider reveals different information about users on its platform, but the pattern for receiving and transforming user data into additional claims is the same.
Decide which external authentication providers to support in the app. For each provider, register the app and obtain a client ID and client secret. For more information, see xref:security/authentication/social/index. The sample app uses the Google authentication provider.
The OAuth authentication provider establishes a trust relationship with an app using a client ID and client secret. Client ID and client secret values are created for the app by the external authentication provider when the app is registered with the provider. Each external provider that the app uses must be configured independently with the provider's client ID and client secret. For more information, see the external authentication provider topics that apply:
- Facebook authentication
- Google authentication
- Microsoft authentication
- Twitter authentication
- Other authentication providers
- OpenIdConnect
Optional claims sent in the ID or access token from the authentication provider are usually configured in the provider's online portal. For example, Microsoft Entra ID permits assigning optional claims to the app's ID token in the app registration's Token configuration blade. For more information, see How to: Provide optional claims to your app (Azure documentation). For other providers, consult their external documentation sets.
The sample app configures the Google authentication provider with a client ID and client secret provided by Google:
Specify the list of permissions to retrieve from the provider by specifying the xref:Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions.Scope*. Authentication scopes for common external providers appear in the following table.
Provider | Scope |
---|---|
https://www.facebook.com/dialog/oauth |
|
profile , email , openid |
|
Microsoft | https://login.microsoftonline.com/common/oauth2/v2.0/authorize |
https://api.twitter.com/oauth/authenticate |
In the sample app, Google's profile
, email
, and openid
scopes are automatically added by the framework when xref:Microsoft.Extensions.DependencyInjection.GoogleExtensions.AddGoogle%2A is called on the xref:Microsoft.AspNetCore.Authentication.AuthenticationBuilder. If the app requires additional scopes, add them to the options. In the following example, the Google https://www.googleapis.com/auth/user.birthday.read
scope is added to retrieve a user's birthday:
options.Scope.Add("https://www.googleapis.com/auth/user.birthday.read");
In the provider's options, specify a xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.MapJsonKey* or xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.MapJsonSubKey* for each key or subkey in the external provider's JSON user data for the app identity to read on sign in. For more information on claim types, see xref:System.Security.Claims.ClaimTypes.
The sample app creates locale (urn:google:locale
) and picture (urn:google:picture
) claims from the locale
and picture
keys in Google user data:
In Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal.ExternalLoginModel.OnPostConfirmationAsync
, an xref:Microsoft.AspNetCore.Identity.IdentityUser (ApplicationUser
) is signed into the app with xref:Microsoft.AspNetCore.Identity.SignInManager%601.SignInAsync*. During the sign in process, the xref:Microsoft.AspNetCore.Identity.UserManager%601 can store an ApplicationUser
claims for user data available from the xref:Microsoft.AspNetCore.Identity.ExternalLoginInfo.Principal*.
In the sample app, OnPostConfirmationAsync
(Account/ExternalLogin.cshtml.cs
) establishes the locale (urn:google:locale
) and picture (urn:google:picture
) claims for the signed in ApplicationUser
, including a claim for xref:System.Security.Claims.ClaimTypes.GivenName:
By default, a user's claims are stored in the authentication cookie. If the authentication cookie is too large, it can cause the app to fail because:
- The browser detects that the cookie header is too long.
- The overall size of the request is too large.
If a large amount of user data is required for processing user requests:
- Limit the number and size of user claims for request processing to only what the app requires.
- Use a custom xref:Microsoft.AspNetCore.Authentication.Cookies.ITicketStore for the Cookie Authentication Middleware's xref:Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions.SessionStore to store identity across requests. Preserve large quantities of identity information on the server while only sending a small session identifier key to the client.
xref:Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions.SaveTokens* defines whether access and refresh tokens should be stored in the xref:Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties after a successful authorization. SaveTokens
is set to false
by default to reduce the size of the final authentication cookie.
The sample app sets the value of SaveTokens
to true
in xref:Microsoft.AspNetCore.Authentication.Google.GoogleOptions:
When OnPostConfirmationAsync
executes, store the access token (ExternalLoginInfo.AuthenticationTokens) from the external provider in the ApplicationUser
's AuthenticationProperties
.
The sample app saves the access token in OnPostConfirmationAsync
(new user registration) and OnGetCallbackAsync
(previously registered user) in Account/ExternalLogin.cshtml.cs
:
Note
For information on passing tokens to the Razor components of a server-side Blazor app, see xref:blazor/security/server/additional-scenarios#pass-tokens-to-a-server-side-blazor-app.
To demonstrate how to add a custom token, which is stored as part of SaveTokens
, the sample app adds an xref:Microsoft.AspNetCore.Authentication.AuthenticationToken with the current xref:System.DateTime for an AuthenticationToken.Name of TicketCreated
:
The framework provides common actions and extension methods for creating and adding claims to the collection. For more information, see the xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions and xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionUniqueExtensions.
Users can define custom actions by deriving from xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction and implementing the abstract xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.Run* method.
For more information, see xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.
Claims are copied from external providers to the user database on first registration, not on sign in. If additional claims are enabled in an app after a user registers to use the app, call SignInManager.RefreshSignInAsync on a user to force the generation of a new authentication cookie.
In the Development environment working with test user accounts, delete and recreate the user account. For production systems, new claims added to the app can be backfilled into user accounts. After scaffolding the ExternalLogin
page into the app at Areas/Pages/Identity/Account/Manage
, add the following code to the ExternalLoginModel
in the ExternalLogin.cshtml.cs
file.
Add a dictionary of added claims. Use the dictionary keys to hold the claim types, and use the values to hold a default value. Add the following line to the top of the class. The following example assumes that one claim is added for the user's Google picture with a generic headshot image as the default value:
Replace the default code of the OnGetCallbackAsync
method with the following code. The code loops through the claims dictionary. Claims are added (backfilled) or updated for each user. When claims are added or updated, the user sign-in is refreshed using the xref:Microsoft.AspNetCore.Identity.SignInManager%601, preserving the existing authentication properties (AuthenticationProperties
).
A similar approach is taken when claims change while a user is signed in but a backfill step isn't required. To update a user's claims, call the following on the user:
- UserManager.ReplaceClaimAsync on the user for claims stored in the identity database.
- SignInManager.RefreshSignInAsync on the user to force the generation of a new authentication cookie.
ClaimActionCollection.Remove(String) removes all claim actions for the given xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.ClaimType from the collection. ClaimActionCollectionMapExtensions.DeleteClaim(ClaimActionCollection, String) deletes a claim of the given xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.ClaimType from the identity. xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.DeleteClaim* is primarily used with OpenID Connect (OIDC) to remove protocol-generated claims.
Run the sample app and select the MyClaims link:
User Claims
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
9b342344f-7aab-43c2-1ac1-ba75912ca999
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
someone@gmail.com
AspNet.Identity.SecurityStamp
7D4312MOWRYYBFI1KXRPHGOSTBVWSFDE
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
Judy
urn:google:locale
en
urn:google:picture
https://lh4.googleusercontent.com/-XXXXXX/XXXXXX/XXXXXX/XXXXXX/photo.jpg
Authentication Properties
.Token.access_token
yc23.AlvoZqz56...1lxltXV7D-ZWP9
.Token.token_type
Bearer
.Token.expires_at
2019-04-11T22:14:51.0000000+00:00
.Token.TicketCreated
4/11/2019 9:14:52 PM
.TokenNames
access_token;token_type;expires_at;TicketCreated
.persistent
.issued
Thu, 11 Apr 2019 20:51:06 GMT
.expires
Thu, 25 Apr 2019 20:51:06 GMT
[!INCLUDEForward request information when behind a proxy or load balancer section]
View or download sample code (how to download)
:::moniker-end
:::moniker range=">= aspnetcore-3.0 < aspnetcore-6.0"
An ASP.NET Core app can establish additional claims and tokens from external authentication providers, such as Facebook, Google, Microsoft, and Twitter. Each provider reveals different information about users on its platform, but the pattern for receiving and transforming user data into additional claims is the same.
View or download sample code (how to download)
Decide which external authentication providers to support in the app. For each provider, register the app and obtain a client ID and client secret. For more information, see xref:security/authentication/social/index. The sample app uses the Google authentication provider.
The OAuth authentication provider establishes a trust relationship with an app using a client ID and client secret. Client ID and client secret values are created for the app by the external authentication provider when the app is registered with the provider. Each external provider that the app uses must be configured independently with the provider's client ID and client secret. For more information, see the external authentication provider topics that apply to your scenario:
- Facebook authentication
- Google authentication
- Microsoft authentication
- Twitter authentication
- Other authentication providers
- OpenIdConnect
Optional claims sent in the ID or access token from the authentication provider are usually configured in the provider's online portal. For example, Microsoft Entra ID permits you to assign optional claims to the app's ID token in the app registration's Token configuration blade. For more information, see How to: Provide optional claims to your app (Azure documentation). For other providers, consult their external documentation sets.
The sample app configures the Google authentication provider with a client ID and client secret provided by Google:
Specify the list of permissions to retrieve from the provider by specifying the xref:Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions.Scope*. Authentication scopes for common external providers appear in the following table.
Provider | Scope |
---|---|
https://www.facebook.com/dialog/oauth |
|
profile , email , openid |
|
Microsoft | https://login.microsoftonline.com/common/oauth2/v2.0/authorize |
https://api.twitter.com/oauth/authenticate |
In the sample app, Google's profile
, email
, and openid
scopes are automatically added by the framework when xref:Microsoft.Extensions.DependencyInjection.GoogleExtensions.AddGoogle%2A is called on the xref:Microsoft.AspNetCore.Authentication.AuthenticationBuilder. If the app requires additional scopes, add them to the options. In the following example, the Google https://www.googleapis.com/auth/user.birthday.read
scope is added to retrieve a user's birthday:
options.Scope.Add("https://www.googleapis.com/auth/user.birthday.read");
In the provider's options, specify a xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.MapJsonKey* or xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.MapJsonSubKey* for each key/subkey in the external provider's JSON user data for the app identity to read on sign in. For more information on claim types, see xref:System.Security.Claims.ClaimTypes.
The sample app creates locale (urn:google:locale
) and picture (urn:google:picture
) claims from the locale
and picture
keys in Google user data:
In Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal.ExternalLoginModel.OnPostConfirmationAsync
, an xref:Microsoft.AspNetCore.Identity.IdentityUser (ApplicationUser
) is signed into the app with xref:Microsoft.AspNetCore.Identity.SignInManager%601.SignInAsync*. During the sign in process, the xref:Microsoft.AspNetCore.Identity.UserManager%601 can store an ApplicationUser
claims for user data available from the xref:Microsoft.AspNetCore.Identity.ExternalLoginInfo.Principal*.
In the sample app, OnPostConfirmationAsync
(Account/ExternalLogin.cshtml.cs
) establishes the locale (urn:google:locale
) and picture (urn:google:picture
) claims for the signed in ApplicationUser
, including a claim for xref:System.Security.Claims.ClaimTypes.GivenName:
By default, a user's claims are stored in the authentication cookie. If the authentication cookie is too large, it can cause the app to fail because:
- The browser detects that the cookie header is too long.
- The overall size of the request is too large.
If a large amount of user data is required for processing user requests:
- Limit the number and size of user claims for request processing to only what the app requires.
- Use a custom xref:Microsoft.AspNetCore.Authentication.Cookies.ITicketStore for the Cookie Authentication Middleware's xref:Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions.SessionStore to store identity across requests. Preserve large quantities of identity information on the server while only sending a small session identifier key to the client.
xref:Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions.SaveTokens* defines whether access and refresh tokens should be stored in the xref:Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties after a successful authorization. SaveTokens
is set to false
by default to reduce the size of the final authentication cookie.
The sample app sets the value of SaveTokens
to true
in xref:Microsoft.AspNetCore.Authentication.Google.GoogleOptions:
When OnPostConfirmationAsync
executes, store the access token (ExternalLoginInfo.AuthenticationTokens) from the external provider in the ApplicationUser
's AuthenticationProperties
.
The sample app saves the access token in OnPostConfirmationAsync
(new user registration) and OnGetCallbackAsync
(previously registered user) in Account/ExternalLogin.cshtml.cs
:
Note
For information on passing tokens to the Razor components of a server-side Blazor app, see xref:blazor/security/server/additional-scenarios#pass-tokens-to-a-server-side-blazor-app.
To demonstrate how to add a custom token, which is stored as part of SaveTokens
, the sample app adds an xref:Microsoft.AspNetCore.Authentication.AuthenticationToken with the current xref:System.DateTime for an AuthenticationToken.Name of TicketCreated
:
The framework provides common actions and extension methods for creating and adding claims to the collection. For more information, see the xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions and xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionUniqueExtensions.
Users can define custom actions by deriving from xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction and implementing the abstract xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.Run* method.
For more information, see xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.
Claims are copied from external providers to the user database on first registration, not on sign in. If additional claims are enabled in an app after a user registers to use the app, call SignInManager.RefreshSignInAsync on a user to force the generation of a new authentication cookie.
In the Development environment working with test user accounts, you can simply delete and recreate the user account. For production systems, new claims added to the app can be backfilled into user accounts. After scaffolding the ExternalLogin
page into the app at Areas/Pages/Identity/Account/Manage
, add the following code to the ExternalLoginModel
in the ExternalLogin.cshtml.cs
file.
Add a dictionary of added claims. Use the dictionary keys to hold the claim types, and use the values to hold a default value. Add the following line to the top of the class. The following example assumes that one claim is added for the user's Google picture with a generic headshot image as the default value:
private readonly IReadOnlyDictionary<string, string> _claimsToSync =
new Dictionary<string, string>()
{
{ "urn:google:picture", "https://localhost:5001/headshot.png" },
};
Replace the default code of the OnGetCallbackAsync
method with the following code. The code loops through the claims dictionary. Claims are added (backfilled) or updated for each user. When claims are added or updated, the user sign-in is refreshed using the xref:Microsoft.AspNetCore.Identity.SignInManager%601, preserving the existing authentication properties (AuthenticationProperties
).
public async Task<IActionResult> OnGetCallbackAsync(
string returnUrl = null, string remoteError = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
return RedirectToPage("./Login", new {ReturnUrl = returnUrl });
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information.";
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}
// Sign in the user with this external login provider if the user already has a
// login.
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider,
info.ProviderKey, isPersistent: false, bypassTwoFactor : true);
if (result.Succeeded)
{
_logger.LogInformation("{Name} logged in with {LoginProvider} provider.",
info.Principal.Identity.Name, info.LoginProvider);
if (_claimsToSync.Count > 0)
{
var user = await _userManager.FindByLoginAsync(info.LoginProvider,
info.ProviderKey);
var userClaims = await _userManager.GetClaimsAsync(user);
bool refreshSignIn = false;
foreach (var addedClaim in _claimsToSync)
{
var userClaim = userClaims
.FirstOrDefault(c => c.Type == addedClaim.Key);
if (info.Principal.HasClaim(c => c.Type == addedClaim.Key))
{
var externalClaim = info.Principal.FindFirst(addedClaim.Key);
if (userClaim == null)
{
await _userManager.AddClaimAsync(user,
new Claim(addedClaim.Key, externalClaim.Value));
refreshSignIn = true;
}
else if (userClaim.Value != externalClaim.Value)
{
await _userManager
.ReplaceClaimAsync(user, userClaim, externalClaim);
refreshSignIn = true;
}
}
else if (userClaim == null)
{
// Fill with a default value
await _userManager.AddClaimAsync(user, new Claim(addedClaim.Key,
addedClaim.Value));
refreshSignIn = true;
}
}
if (refreshSignIn)
{
await _signInManager.RefreshSignInAsync(user);
}
}
return LocalRedirect(returnUrl);
}
if (result.IsLockedOut)
{
return RedirectToPage("./Lockout");
}
else
{
// If the user does not have an account, then ask the user to create an
// account.
ReturnUrl = returnUrl;
ProviderDisplayName = info.ProviderDisplayName;
if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
{
Input = new InputModel
{
Email = info.Principal.FindFirstValue(ClaimTypes.Email)
};
}
return Page();
}
}
A similar approach is taken when claims change while a user is signed in but a backfill step isn't required. To update a user's claims, call the following on the user:
- UserManager.ReplaceClaimAsync on the user for claims stored in the identity database.
- SignInManager.RefreshSignInAsync on the user to force the generation of a new authentication cookie.
ClaimActionCollection.Remove(String) removes all claim actions for the given xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.ClaimType from the collection. ClaimActionCollectionMapExtensions.DeleteClaim(ClaimActionCollection, String) deletes a claim of the given xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.ClaimType from the identity. xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.DeleteClaim* is primarily used with OpenID Connect (OIDC) to remove protocol-generated claims.
User Claims
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
9b342344f-7aab-43c2-1ac1-ba75912ca999
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
someone@gmail.com
AspNet.Identity.SecurityStamp
7D4312MOWRYYBFI1KXRPHGOSTBVWSFDE
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
Judy
urn:google:locale
en
urn:google:picture
https://lh4.googleusercontent.com/-XXXXXX/XXXXXX/XXXXXX/XXXXXX/photo.jpg
Authentication Properties
.Token.access_token
yc23.AlvoZqz56...1lxltXV7D-ZWP9
.Token.token_type
Bearer
.Token.expires_at
2019-04-11T22:14:51.0000000+00:00
.Token.TicketCreated
4/11/2019 9:14:52 PM
.TokenNames
access_token;token_type;expires_at;TicketCreated
.persistent
.issued
Thu, 11 Apr 2019 20:51:06 GMT
.expires
Thu, 25 Apr 2019 20:51:06 GMT
[!INCLUDEForward request information when behind a proxy or load balancer section]
:::moniker-end
:::moniker range="< aspnetcore-3.0"
An ASP.NET Core app can establish additional claims and tokens from external authentication providers, such as Facebook, Google, Microsoft, and Twitter. Each provider reveals different information about users on its platform, but the pattern for receiving and transforming user data into additional claims is the same.
View or download sample code (how to download)
Decide which external authentication providers to support in the app. For each provider, register the app and obtain a client ID and client secret. For more information, see xref:security/authentication/social/index. The sample app uses the Google authentication provider.
The OAuth authentication provider establishes a trust relationship with an app using a client ID and client secret. Client ID and client secret values are created for the app by the external authentication provider when the app is registered with the provider. Each external provider that the app uses must be configured independently with the provider's client ID and client secret. For more information, see the external authentication provider topics that apply to your scenario:
- Facebook authentication
- Google authentication
- Microsoft authentication
- Twitter authentication
- Other authentication providers
- OpenIdConnect
The sample app configures the Google authentication provider with a client ID and client secret provided by Google:
Specify the list of permissions to retrieve from the provider by specifying the xref:Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions.Scope*. Authentication scopes for common external providers appear in the following table.
Provider | Scope |
---|---|
https://www.facebook.com/dialog/oauth |
|
https://www.googleapis.com/auth/userinfo.profile |
|
Microsoft | https://login.microsoftonline.com/common/oauth2/v2.0/authorize |
https://api.twitter.com/oauth/authenticate |
In the sample app, Google's userinfo.profile
scope is automatically added by the framework when xref:Microsoft.Extensions.DependencyInjection.GoogleExtensions.AddGoogle* is called on the xref:Microsoft.AspNetCore.Authentication.AuthenticationBuilder. If the app requires additional scopes, add them to the options. In the following example, the Google https://www.googleapis.com/auth/user.birthday.read
scope is added in order to retrieve a user's birthday:
options.Scope.Add("https://www.googleapis.com/auth/user.birthday.read");
In the provider's options, specify a xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.MapJsonKey* or xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.MapJsonSubKey* for each key/subkey in the external provider's JSON user data for the app identity to read on sign in. For more information on claim types, see xref:System.Security.Claims.ClaimTypes.
The sample app creates locale (urn:google:locale
) and picture (urn:google:picture
) claims from the locale
and picture
keys in Google user data:
In Microsoft.AspNetCore.Identity.UI.Pages.Account.Internal.ExternalLoginModel.OnPostConfirmationAsync
, an xref:Microsoft.AspNetCore.Identity.IdentityUser (ApplicationUser
) is signed into the app with xref:Microsoft.AspNetCore.Identity.SignInManager%601.SignInAsync*. During the sign in process, the xref:Microsoft.AspNetCore.Identity.UserManager%601 can store an ApplicationUser
claims for user data available from the xref:Microsoft.AspNetCore.Identity.ExternalLoginInfo.Principal*.
In the sample app, OnPostConfirmationAsync
(Account/ExternalLogin.cshtml.cs
) establishes the locale (urn:google:locale
) and picture (urn:google:picture
) claims for the signed in ApplicationUser
, including a claim for xref:System.Security.Claims.ClaimTypes.GivenName:
By default, a user's claims are stored in the authentication cookie. If the authentication cookie is too large, it can cause the app to fail because:
- The browser detects that the cookie header is too long.
- The overall size of the request is too large.
If a large amount of user data is required for processing user requests:
- Limit the number and size of user claims for request processing to only what the app requires.
- Use a custom xref:Microsoft.AspNetCore.Authentication.Cookies.ITicketStore for the Cookie Authentication Middleware's xref:Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationOptions.SessionStore to store identity across requests. Preserve large quantities of identity information on the server while only sending a small session identifier key to the client.
xref:Microsoft.AspNetCore.Authentication.RemoteAuthenticationOptions.SaveTokens* defines whether access and refresh tokens should be stored in the xref:Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties after a successful authorization. SaveTokens
is set to false
by default to reduce the size of the final authentication cookie.
The sample app sets the value of SaveTokens
to true
in xref:Microsoft.AspNetCore.Authentication.Google.GoogleOptions:
When OnPostConfirmationAsync
executes, store the access token (ExternalLoginInfo.AuthenticationTokens) from the external provider in the ApplicationUser
's AuthenticationProperties
.
The sample app saves the access token in OnPostConfirmationAsync
(new user registration) and OnGetCallbackAsync
(previously registered user) in Account/ExternalLogin.cshtml.cs
:
To demonstrate how to add a custom token, which is stored as part of SaveTokens
, the sample app adds an xref:Microsoft.AspNetCore.Authentication.AuthenticationToken with the current xref:System.DateTime for an AuthenticationToken.Name of TicketCreated
:
The framework provides common actions and extension methods for creating and adding claims to the collection. For more information, see the xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions and xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionUniqueExtensions.
Users can define custom actions by deriving from xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction and implementing the abstract xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.Run* method.
For more information, see xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.
ClaimActionCollection.Remove(String) removes all claim actions for the given xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.ClaimType from the collection. ClaimActionCollectionMapExtensions.DeleteClaim(ClaimActionCollection, String) deletes a claim of the given xref:Microsoft.AspNetCore.Authentication.OAuth.Claims.ClaimAction.ClaimType from the identity. xref:Microsoft.AspNetCore.Authentication.ClaimActionCollectionMapExtensions.DeleteClaim* is primarily used with OpenID Connect (OIDC) to remove protocol-generated claims.
User Claims
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
9b342344f-7aab-43c2-1ac1-ba75912ca999
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
someone@gmail.com
AspNet.Identity.SecurityStamp
7D4312MOWRYYBFI1KXRPHGOSTBVWSFDE
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
Judy
urn:google:locale
en
urn:google:picture
https://lh4.googleusercontent.com/-XXXXXX/XXXXXX/XXXXXX/XXXXXX/photo.jpg
Authentication Properties
.Token.access_token
yc23.AlvoZqz56...1lxltXV7D-ZWP9
.Token.token_type
Bearer
.Token.expires_at
2019-04-11T22:14:51.0000000+00:00
.Token.TicketCreated
4/11/2019 9:14:52 PM
.TokenNames
access_token;token_type;expires_at;TicketCreated
.persistent
.issued
Thu, 11 Apr 2019 20:51:06 GMT
.expires
Thu, 25 Apr 2019 20:51:06 GMT
[!INCLUDEForward request information when behind a proxy or load balancer section]
:::moniker-end
- dotnet/AspNetCore engineering SocialSample app: The linked sample app is on the dotnet/AspNetCore GitHub repo's
main
engineering branch. Themain
branch contains code under active development for the next release of ASP.NET Core. To see a version of the sample app for a released version of ASP.NET Core, use the Branch drop down list to select a release branch (for examplerelease/{X.Y}
).