当你使用await _userManager.AddClaimAsync(user, new Claim("your-claim", "your-value"));
这实际上更新了 Identity 的 aspnetuserclaims 表。
每当您登录(通过使用 _signInManager.PasswordSignIn 或 _signInManager.ExternalLoginSignInAsync)时,都会读取该表中的声明并将其添加到 cookie,该 cookie 在每个请求上都会成为主体。
因此,您可能不希望在每次登录时从 UserManager 调用 AddClaimAsync 方法。
关于外部登录提供程序,您可以在此处调用时访问声明(如果您使用默认模板,则在ExternalCallback和ExternalCallbackConfirmation中):
var info = await _signInManager.GetExternalLoginInfoAsync();
索赔是在info.Principal.Claims
.
默认情况下不包含访问令牌。如果是的话,它会在这里(以及类型和到期日期):
var accessToken = info.AuthenticationTokens.Single(f => f.Name == "access_token").Value;
var tokenType = info.AuthenticationTokens.Single(f => f.Name == "token_type").Value;
var expiryDate = info.AuthenticationTokens.Single(f => f.Name == "expires_at").Value;
要将访问令牌包含在AuthenticationTokens
集合,当您配置 GoogleAuthentication 中间件时,将 SaveTokens 标志设置为 true:
app.UseGoogleAuthentication(new GoogleOptions{
ClientId = "...",
ClientSecret = "...",
SaveTokens = true
现在,如果您想控制 cookie 中包含哪些声明,您必须“接管”创建声明主体的过程。
这是在您使用时为您完成的_signInManager.PasswordSignIn/ExternalLoginSignInAsync
.
因此,例如,对于ExternalLoginSignInAsync
代替:
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
With:
var user = await this._userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
var claimsPrincipal = await this._signInManager.CreateUserPrincipalAsync(user);
((ClaimsIdentity)claimsPrincipal.Identity).AddClaim(new Claim("accessToken", info.AuthenticationTokens.Single(t => t.Name == "access_token").Value));
await HttpContext.Authentication.SignInAsync("Identity.Application", claimsPrincipal);
“Identity.Application”是默认的 cookie 名称。您可以在启动项中更改它ConfigureServices
方法,例如 MainCookie:
services.Configure<IdentityOptions>(options => {
options.Cookies.ApplicationCookie.AuthenticationScheme = "MainCookie";
});
您仍然需要处理ExternalCallbackConfirmation
AccountController 中的操作。它将与上面的示例类似。