asp.net core身份提取并保存外部登录令牌并向本地身份添加声明

2023-11-27

我是一个 stackoverflow 菜鸟,所以如果我做错了,请放轻松。

我使用带有默认核心身份模板(本地帐户)的 asp.net core。

我已经确定了当用户在本地登录时如何向用户主体添加声明,如下所示

[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 中,无论用户如何登录(本地或外部),以及如何在需要时将这些声明保留到数据库中。

我计划做一些工作,如果我有一个使用 google auth 的用户登录,我需要保存来自 google 的 access_token,因为我希望稍后用它调用 Google API。因此,我需要能够将此 access_token 包含在创建的用户主体中,并且我希望 cookie 对其有一个声明,我也可以在前端使用。

这可能超出了这个问题的范围,但我也想当谷歌令牌过期时,以某种方式使用刷新令牌并获取新的令牌,或者强制用户重新登录。

对此的任何帮助将非常感激,我真的很努力地理解这一点,而没有将这个问题发布到 stackoverflow。我读过很多文章,其中包含很多有用的信息,但没有提供这个特定问题所要求的答案。非常感谢您。

cheers


当你使用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";
        });

您仍然需要处理ExternalCallbackConfirmationAccountController 中的操作。它将与上面的示例类似。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

asp.net core身份提取并保存外部登录令牌并向本地身份添加声明 的相关文章

随机推荐