[英].Net Core 2 OpenID Connect Authentication and multiple Identities
I'm still learning the Identity Framework and am pretty lost in trying to setup authentication in my .Net Core 2 MVC application. 我仍在学习Identity Framework,并且在尝试在我的.Net Core 2 MVC应用程序中设置身份验证时非常迷失。 Any suggestions are appreciated since I'm not even sure what I'm doing is correct. 感谢我提供任何建议,因为我什至不确定自己在做什么。
I have a requirement to integrate an OpenID Connect identity provider for authentication and use a secondary data source for authorization . 我需要集成OpenID Connect身份提供程序进行身份验证,并使用辅助数据源进行授权 。 Inconveniently I cannot use any claim from the OIDC IdP except for the name claim. 除名称声明外,我不方便使用OIDC IdP的任何声明。 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). 其余的用户声明必须来自辅助数据源(通过自定义UserStore
和User
实体连接到Identity Framework)。
I am using the OpenId Connect provider to handle the authentication. 我正在使用OpenId Connect提供程序来处理身份验证。 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
. 当我需要获取用户的第二个Identity并将其添加到主体,并将其设置为默认Identity
时,我的困惑就开始了。 This second Identity
provides all of the user claims, including role. 此第二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. 我对身份框架的理解是,我应该有一个具有两个身份的单个ClaimsPrincipal
,以便可以插入身份框架的其余部分。 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. 但是,对于两个身份,默认的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
}
}
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. 从OIDC IdP获得经过验证的令牌后,我将获取第二个身份,创建一个新的MyClaimsPrincipal,然后将两个身份添加到新的主体中。 After that I'm not sure what to do with this new principal. 之后,我不确定该如何处理新的校长。
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. 我试图通过SignInManager
登录用户,在HTTP上下文中显式设置User,并使用中间件将ClaimsPrincipals
转换为MyClaimsPrincipals
但所有这些似乎都无济于事。 I think I am missing the point. 我想我没说清楚。
Some specific questions: 一些具体问题:
An important thing to know when using the OpenID Connect scheme is that the scheme will never work on its own. 使用OpenID Connect方案时要了解的重要一点是,该方案永远不会独立运行。 In pretty much every example you can find you will see it combined with the cookie scheme. 在几乎每个示例中,您都可以找到它与cookie方案的结合。 The reason for this is very simple: OIDC is for authenticating the user with an external authentication provider. 原因很简单:OIDC用于通过外部身份验证提供程序对用户进行身份验证。 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). 这通常是通过Cookie身份验证方案完成的(尽管它可以通过其他方式完成)。
The authentication flow for an application that uses OIDC and cookies usually works like this: 使用OIDC和Cookie的应用程序的身份验证流程通常如下所示:
So assuming that everything worked properly, the OIDC scheme will not be involved again in the authentication. 因此,假设一切正常,OIDC方案将不再参与身份验证。 Instead, the identity from the cookie will be used every time. 而是每次都会使用cookie中的身份。
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. 您可以将其用于您的目的,以扩展OIDC方案使用其他声明创建的主体,然后再通过Cookie方案对其进行登录和持久化。 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. 你可以做到这一点使用自定义签入方案的OIDC和饼干方案之间坐镇,或者你可以简单地连接到挑战完成后出现登录之前被调用,但OIDC方案的认证活动。
You can use the TicketReceived
event for this purpose: 您可以将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.