通过 openid 提供商在 ASP.NET Core 2.0 中授权

Authorization in ASP.NET Core 2.0 via openid provider

我在将声明从外部身份传递给本地身份时遇到问题。该应用程序基本上是添加了 openid 身份提供程序的 QuickBooksASPNetCore2 Demo。除了

之外,一切都可以正常工作

[Authorize(Role = "some_role")]

在测试 Razer 页面上。

这是执行登录逻辑的代码,

_signInManager.GetExternalLoginInfoAsync();

return 身份提供者的所有声明的主体(包括“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”类型下的角色)。

dump of info var with claims

 public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, string remoteError = null)
    {
        if (remoteError != null)
        {
            ErrorMessage = $"Error from external provider: {remoteError}";
            return RedirectToPage("./Login");
        }
        var info = await _signInManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return RedirectToPage("./Login");
        }

        // 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: true, bypassTwoFactor : true);
        if (result.Succeeded)
        {
            _logger.LogInformation("{Name} logged in with {LoginProvider} provider.", info.Principal.Identity.Name, info.LoginProvider);
            await _signInManager.UpdateExternalAuthenticationTokensAsync(info);
            return LocalRedirect(Url.GetLocalUrl(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;
            LoginProvider = info.LoginProvider;
            if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
            {
                Input = new InputModel
                {
                    Email = info.Principal.FindFirstValue(ClaimTypes.Email)
                };
            }
            return Page();
        }
    }

但是当此方法退出时,Razor 页面上的 User.Claims 没有角色声明。它甚至获得了新的“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier”声明(具有不同的 ID)。我在这里错过了什么吗?

因此,如果有人遇到此问题,您需要将声明从外部身份映射到本地应用程序身份。

这意味着替换行

var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: true, bypassTwoFactor : true);

var user = await _userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
var claimsPrincipal = await this._signInManager.CreateUserPrincipalAsync(user);
((ClaimsIdentity)claimsPrincipal.Identity).AddClaims(info.Principal.Claims.Where(c => c.Type == ClaimTypes.Role));

await HttpContext.SignInAsync("Identity.Application", claimsPrincipal);

您在应用程序中需要的所有声明,您需要使用来自外部身份的 AddClaim(s) 方法手动映射。