.Net Core 2 OpenID Connect身份验证和多个身份 [英] .Net Core 2 OpenID Connect Authentication and multiple Identities

查看:100
本文介绍了.Net Core 2 OpenID Connect身份验证和多个身份的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm still learning the Identity Framework and am pretty lost in trying to setup authentication in my .Net Core 2 MVC application. Any suggestions are appreciated since I'm not even sure what I'm doing is correct.

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

I have a requirement to integrate an OpenID Connect identity provider for authentication and use a secondary data source for authorization. Inconveniently I cannot use any claim from the OIDC IdP except for the name claim. The rest of the user claims must come from the secondary data source (which is connected to the Identity Framework through a custom UserStore and User entity).

我正在使用

I am using the OpenId Connect provider to handle the authentication. This is working fine and gives me the first Identity (which I can only use one Claim from). My confusion starts when I need to fetch the second Identity of the user, add it to the principal, and set it as the default Identity. This second Identity provides all of the user claims, including role.

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

My understanding of identity framework is that I should have a single ClaimsPrincipal with two identities so that I can plug into the rest of Identity Framework. However with two identities the default ClaimsPrincipal will automatically select the first Identity (which is the one I can't use), therefor it seems I should create a custom ClaimsPrincipal and set the PrimaryIdentitySelector so that my second Identity is the primary.

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,然后将两个身份添加到新的主体中.之后,我不确定该新校长该怎么办.

Once I get the validated token from the OIDC IdP, I fetch the second identity, create a new MyClaimsPrincipal, add the two Identities to the new principal. After that I'm not sure what to do with this new principal.

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

I've tried to sign the user in via the SignInManager, setting the User on the HTTP context explicitly, and using middleware to convert ClaimsPrincipals to MyClaimsPrincipals but all of these seem to do nothing. I think I am missing the point.

一些具体问题:

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

推荐答案

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

An important thing to know when using the OpenID Connect scheme is that the scheme will never work on its own. In pretty much every example you can find you will see it combined with the cookie scheme. The reason for this is very simple: OIDC is for authenticating the user with an external authentication provider. But that authentication is only temporary. In order to store it locally within your application, you need to sign in your user. This is usually done with the cookie authentication scheme (although it could be done in other ways).

使用OIDC和cookie的应用程序的身份验证流程通常是这样的:

The authentication flow for an application that uses OIDC and cookies usually works like this:

  1. 用户访问您的应用程序.
  2. 身份验证:Cookie方案(默认身份验证方案)将尝试对用户进行身份验证.如果没有cookie,则处理程序将挑战进行身份验证.
  3. 挑战:OIDC方案(默认的挑战方案)将挑战用户并重定向到外部身份验证提供程序.
  4. 用户将通过外部身份验证提供程序进行身份验证,并将重定向到应用程序.
  5. 挑战回调:OIDC方案将从外部身份验证提供程序获得响应,完成挑战并创建声明主体.
  6. 登录:OIDC方案将使用其配置的登录方案(cookie方案)登录该主体.
  7. 该cookie方案将登录用户并创建一个持久保存在用户浏览器中的cookie.
  8. 在对您的应用程序的后续请求中,用户将包括有效的cookie,因此cookie方案可以成功验证用户身份,而无需再次挑战OIDC方案.
  1. User accesses your application.
  2. Authentication: The cookie scheme, the default authentication scheme, will attempt to authenticate the user. If there is no cookie, the handler will challenge the authentication.
  3. Challenge: The OIDC scheme, the default challenge scheme, will challenge the user and redirect to the external authentication provider.
  4. The user will authenticate with the external authentication provider and will get redirected back to the application.
  5. Challenge callback: The OIDC scheme will take the response from the external authentication provider, complete the challenge and create a claims principal.
  6. Sign-in: The OIDC scheme will sign in that principal with its configured sign-in scheme (the cookie scheme).
  7. The cookie scheme will sign in the user and create a cookie that is persisted in the user’s browser.
  8. On a subsequent request to your application, the user will include a valid cookie, so the cookie schem can successfully authenticate the user, without having to challenge the OIDC scheme again.

因此,假设一切正常,OIDC方案将不再涉及身份验证.取而代之的是,每次都会使用Cookie中的身份.

So assuming that everything worked properly, the OIDC scheme will not be involved again in the authentication. Instead, the identity from the cookie will be used every time.

您可以将其用于您的目的,以扩展OIDC方案使用其他声明创建的主体,然后再通过Cookie方案对其进行登录和持久化.您可以使用位于OIDC和cookie方案之间的自定义登录方案来执行此操作,或者可以简单地附加到在挑战完成后 调用的OIDC方案的身份验证事件,但是之前进行登录.

You can use this for your purpose to expand the principal that the OIDC scheme created with additional claims, before it is signed in and persisted by the cookie scheme. You could do this using a custom sign-in scheme that sits between the OIDC and cookie schemes, or you could simply attach to an authentication event of the OIDC scheme that is invoked after the challenge is completed but before the sign-in occurs.

您可以使用

You can use the TicketReceived event for this purpose:

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;
}

这篇关于.Net Core 2 OpenID Connect身份验证和多个身份的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆