支持多个相同类型的AuthenticationSchemes
Support multiple AuthenticationSchemes of same type
我正在使用 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
和 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");
});
我正在使用 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
和 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");
});