繁体   English   中英

.Net Core 2 OpenID Connect身份验证和多个身份

[英].Net Core 2 OpenID Connect Authentication and multiple Identities

我仍在学习Identity Framework,并且在尝试在我的.Net Core 2 MVC应用程序中设置身份验证时非常迷失。 感谢我提供任何建议,因为我什至不确定自己在做什么。


我需要集成OpenID Connect身份提供程序进行身份验证,并使用辅助数据源进行授权 除名称声明外,我不方便使用OIDC IdP的任何声明。 其余的用户声明必须来自辅助数据源(通过自定义UserStoreUser实体连接到Identity Framework)。

我正在使用OpenId Connect提供程序来处理身份验证。 这工作正常,并为我提供了第一个身份(我只能使用一个索赔)。 当我需要获取用户的第二个Identity并将其添加到主体,并将其设置为默认Identity时,我的困惑就开始了。 此第二Identity提供了所有用户声明,包括角色。

我对身份框架的理解是,我应该有一个具有两个身份的单个ClaimsPrincipal ,以便可以插入身份框架的其余部分。 但是,对于两个身份,默认的ClaimsPrincipal将自动选择第一个Identity(这是我不能使用的身份),因此,似乎我应该创建一个自定义ClaimsPrincipal并设置PrimaryIdentitySelector以使我的第二个Identity为主要身份。

public class MyClaimsPrincipal : ClaimsPrincipal
{
    private static readonly Func<IEnumerable<ClaimsIdentity>, ClaimsIdentity> IdentitySelector = SelectPrimaryIdentity;

    /// <summary>
    /// This method iterates through the collection of ClaimsIdentities and chooses an identity as the primary.
    /// </summary>
    private static ClaimsIdentity SelectPrimaryIdentity(IEnumerable<ClaimsIdentity> identities)
    {
        // Find and return the second identity
    }
}

从OIDC IdP获得经过验证的令牌后,我将获取第二个身份,创建一个新的MyClaimsPrincipal,然后将两个身份添加到新的主体中。 之后,我不确定该如何处理新的校长。

我试图通过SignInManager登录用户,在HTTP上下文中显式设置User,并使用中间件将ClaimsPrincipals转换为MyClaimsPrincipals但所有这些似乎都无济于事。 我想我没说清楚。

一些具体问题:

  • 这是最好的方法吗? 人们普遍对所有这些事情感到困惑,这使得很难判断我是否走上了正确的道路。
  • 创建自定义主体后,如何将其“设置”到HTTP上下文中以使其持久化?
  • Cookie身份验证如何与OpenId Connect身份验证一起使用? 似乎OIDC以某种方式将用户传递到Cookie身份验证,并且需要添加cookie身份验证才能使OIDC身份验证正常工作。

使用OpenID Connect方案时要了解的重要一点是,该方案永远不会独立运行。 在几乎每个示例中,您都可以找到它与cookie方案的结合。 原因很简单:OIDC用于通过外部身份验证提供程序对用户进行身份验证。 但是该身份验证只是暂时的。 为了将其本地存储在应用程序中,您需要登录用户。 这通常是通过Cookie身份验证方案完成的(尽管它可以通过其他方式完成)。

使用OIDC和Cookie的应用程序的身份验证流程通常如下所示:

  1. 用户访问您的应用程序。
  2. 身份验证 :cookie方案(默认身份验证方案)将尝试对用户进行身份验证。 如果没有cookie,则处理程序将挑战身份验证。
  3. 质询 :OIDC方案(默认质询方案)将质询用户并重定向到外部身份验证提供程序。
  4. 用户将通过外部身份验证提供程序进行身份验证,并将重定向到应用程序。
  5. 质询回调 :OIDC方案将从外部身份验证提供程序获得响应,完成质询并创建声明主体。
  6. 登录 :OIDC方案将使用其配置的登录方案(cookie方案)登录该主体。
  7. cookie方案将登录用户并创建一个持久保存在用户浏览器中的cookie。
  8. 在对您的应用程序的后续请求中,用户将包括有效的cookie,因此cookie方案可以成功验证用户身份,而无需再次挑战OIDC方案。

因此,假设一切正常,OIDC方案将不再参与身份验证。 而是每次都会使用cookie中的身份。

您可以将其用于您的目的,以扩展OIDC方案使用其他声明创建的主体,然后再通过Cookie方案对其进行登录和持久化。 你可以做到这一点使用自定义签入方案的OIDC和饼干方案之间坐镇,或者你可以简单地连接到挑战完成出现登录之前被调用,但OIDC方案的认证活动。

您可以将TicketReceived事件用于此目的:

public void ConfigureServices(IServiceCollection services)
{
    // …

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
        .AddCookie()
        .AddOpenIdConnect(options =>
        {
            // …

            options.Events.OnTicketReceived = OnOpenIdConnectTicketReceived;
        });
}

public static Task OnOpenIdConnectTicketReceived(TicketReceivedContext context)
{
    if (context.Principal.Identity is ClaimsIdentity identity)
    {
        identity.AddClaim(new Claim("foo", "bar"));
    }

    return Task.CompletedTask;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM