【问题标题】:Support multiple AuthenticationSchemes of same type支持多个相同类型的AuthenticationSchemes
【发布时间】:2018-04-08 11:12:59
【问题描述】:

我正在使用 IdentityServer4 并尝试添加多个相同类型的外部提供程序,在我的例子中是 OpenIdConnect。但是我遇到了一些问题。

services.AddAuthentication()
// Azure AD
.AddOpenIdConnect("oidc", "Azure AD", x =>
{
    x.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    x.SignOutScheme = IdentityServerConstants.SignoutScheme;
    x.ClientId = "some-client-id";
    x.Authority = "https://login.microsoftonline.com/common";
    x.ResponseType = OpenIdConnectResponseType.IdToken;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = false
    };
})
// Identity Server
.AddOpenIdConnect("oidc", "My Other Identity Server", x =>
{
    x.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    x.SignOutScheme = IdentityServerConstants.SignoutScheme;
    x.ClientId = "some-other-client-id";
    x.Authority = "http://localhost:6000"; //Another Identity Server I want to treat as external provider
    x.RequireHttpsMetadata = false;
    x.ResponseType = OpenIdConnectResponseType.IdToken;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true
    };
});

原因:

Scheme already exists: oidc
   at Microsoft.AspNetCore.Authentication.AuthenticationOptions.AddScheme(String name, Action`1 configureBuilder)
   at Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0`2.<AddScheme>b__0(AuthenticationOptions o)
   at Microsoft.Extensions.Options.ConfigureNamedOptions`1.Configure(String name, TOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.<>c__DisplayClass5_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
   at Microsoft.Extensions.Options.OptionsManager`1.Get(String name)
   at Microsoft.Extensions.Options.OptionsManager`1.get_Value()
   at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions`1 options)
services.AddAuthentication()
// Azure AD
.AddOpenIdConnect("oidc", "Azure AD", x =>
{
    x.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    x.SignOutScheme = IdentityServerConstants.SignoutScheme;
    x.ClientId = "some-client-id";
    x.Authority = "https://login.microsoftonline.com/common";
    x.ResponseType = OpenIdConnectResponseType.IdToken;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = false
    };
})
// Identity Server
.AddOpenIdConnect("oidc-idserver", "My Other Identity Server", x =>
{
    x.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    x.SignOutScheme = IdentityServerConstants.SignoutScheme;
    x.ClientId = "some-other-client-id";
    x.Authority = "http://localhost:6000"; //Another Identity Server I want to treat as external provider
    x.RequireHttpsMetadata = false;
    x.ResponseType = OpenIdConnectResponseType.IdToken;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true
    };
});

如果我给他们不同的方案,那么当外部提供者回发时,我会得到以下异常。

原因:

Exception: Correlation failed.
  Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler+<HandleRequestAsync>d__12.MoveNext()

【问题讨论】:

  • 还没有尝试过这种情况,所以我不确定:您可以尝试向两个处理程序添加 CallbackPath 吗?例如。 /aad-callback 和 /idserver-callback。然后,您需要在两个提供商上配置回复 URL 有点不同。
  • 我认为 junnas 是正确的,“相关失败”错误是由于每个提供者没有不同的回调 URL。在我的情况下,我需要它基于与用户的电子邮件域关联的配置进行数据驱动,因此创建了我自己的中间件,它可以接受它需要的所有设置,值传递给 Challenge 方法的属性。
  • @eugene-s,您的代码库的哪一部分有逻辑选择 oidc 身份验证方案(“oidc”或“oidc-idserver”)之一?你能分享一下这段代码的样子吗?
  • 您必须使用 ChallengeAsync 并传入方案。 docs.microsoft.com/en-us/dotnet/api/… 。您向用户呈现的方式是为每个方案呈现不同的按钮,然后引发 ChallengeAsync。

标签: asp.net-core-mvc openid-connect identityserver4 asp.net-core-2.0


【解决方案1】:

正如评论者所建议的,解决方案是添加特定的 CallbackPath 和 SignedOutCallbackPath,以便中间件可以知道哪个外部提供程序正在运行。

services.AddAuthentication()
// Azure AD
.AddOpenIdConnect("oidc", "Azure AD", x =>    
{
    x.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    x.SignOutScheme = IdentityServerConstants.SignoutScheme;
    x.ClientId = "some-client-id";
    x.Authority = "https://login.microsoftonline.com/common";
    x.ResponseType = OpenIdConnectResponseType.IdToken;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = false
    };

    // Callbacks for middleware to properly correlate
    x.CallbackPath = new PathString("/signin-oidc-az");
    x.SignedOutCallbackPath = new PathString("/signout-oidc-az");
})
// Identity Server
.AddOpenIdConnect("oidc-idserver", "My Other Identity Server", x =>    
{
    x.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    x.SignOutScheme = IdentityServerConstants.SignoutScheme;
    x.ClientId = "some-other-client-id";
    x.Authority = "http://localhost:6000"; //Another Identity Server I want to treat as external provider
    x.RequireHttpsMetadata = false;
    x.ResponseType = OpenIdConnectResponseType.IdToken;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true
    };

    // Callbacks for middleware to properly correlate
    x.CallbackPath = new PathString("/signin-oidc-so");
    x.SignedOutCallbackPath = new PathString("/signout-oidc-so");
});

【讨论】:

  • 嗨,您能否展示或解释新端点的配置(CallbackPath、SignedOutCallbackPath)、调用某些 bsae signin-oidc 和 signout-oidc 的新方法?
  • 特定的 CallbackPath 和 SignedOutCallbackPath 您将在目标身份提供者中配置为允许的站点。因此,当目标身份提供者回发时,它会回发到您在 CallbackPath 中配置的路由,并且 Oidc 中间件将选择要使用的正确配置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
相关资源
最近更新 更多