asp.net核心身份提取并保存外部登录令牌并将声明添加到本地身份
我是一个* noob,所以如果我这样做错了,请尽量轻松。asp.net核心身份提取并保存外部登录令牌并将声明添加到本地身份
我使用默认的核心身份模板(本地帐户)的asp.net核心。
我已经accertained如何索赔添加到用户主体时,他们在本地登录,像这样
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model)
{
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var user = await _userManager.FindByNameAsync(model.Email);
await _userManager.AddClaimAsync(user, new Claim("your-claim", "your-value"));
我想通了如何从外部登录返回指控,但我不知道我是怎么想补充用户主体获取的ExternalLoginCallback功能创造了这些前
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
if (remoteError != null)
{
ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}");
return View(nameof(Login));
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return RedirectToAction(nameof(Login));
}
else {
// extract claims from external token here
}
// assume add claims to user here before cookie gets created??
// 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);
if (result.Succeeded)
我假设的_signInManager.ExternalLoginSignInAsync功能的工作原理类似于在这个意义上本地登录_signInManager.PasswordSignInAsync,一旦它被调用,cookie将被创建。但我不确定。
本质上,我希望实现的是了解如何将自定义声明添加到创建的cookie中,而不管用户如何登录(本地或外部),以及如何在需要时将这些声明持久保存到数据库。
我打算做一些工作,如果我有一个用户登录使用说谷歌认证,我需要从谷歌保存access_token,因为我希望随后调用Google API。所以我需要能够将这个access_token包含在创建的用户主体中,并且我希望cookie可以在前端使用它。
这可能超出了这个问题的范围,但我也想当谷歌令牌到期,对于某些 - 如何使用刷新令牌并去获取新的令牌,或强制用户重新登录。
对此的任何帮助将超级赞赏,我真的很努力去理解这个没有发布这个问题到*。我阅读了很多有用信息的文章,但没有提供这个具体问题所要求的答案。所以非常感谢你提前。
欢呼
当您使用await _userManager.AddClaimAsync(user, new Claim("your-claim", "your-value"));
实际更新标识的aspnetuserclaims表。
无论您何时登录(通过使用_signInManager.PasswordSignIn或_signInManager.ExternalLoginSignInAsync),都会读取该表中的声明并将其添加到每个请求成为主体的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);
有了:
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";
});
你仍然需要以处理的AccountController的ExternalCallbackConfirmation
行动。它将与上面的示例类似。