对于我的网站,我正在使用OWIN OpenId与第三方身份验证提供程序进行集成,以允许访问者注册/登录/注销。 “秒”
我的应用程序还有一个测试环境,在将这些更改推送到生产环境之前测试所有代码更改。我使用OWIN OpenId以及“First”来保护测试环境免受与另一个第三方认证提供者的公共访问。只有经过身份验证的访问者才能访问测试环境网站。
现在问题是这些都是独立的,但我似乎无法将它们结合起来。我想要实现的是,我可以通过使用First进行身份验证来访问测试环境,然后,作为regluar访问者,使用Second进行身份验证,以查看为注册访问者设计的内容。
这就是我正在做的事情:
两个authnetication提供程序都使用cookie身份验证,但我给了他们一个不同的AuthenticationType来保持它们分开。
if (IsEnabled("First"))
app.SetDefaultSignInAsAuthenticationType("First");
else
app.SetDefaultSignInAsAuthenticationType("Second");
// Configure First.
if (IsEnabled("First")) {
app.UseCookieAuthentication(First.CookieAuthenticationOptions); // AuthenticationType is set to "First" in these options.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = First.AADClientId,
Authority = First.Authority,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context => { ... },
RedirectToIdentityProvider = context => { ... }
},
AuthenticationType = "First"
});
app.Map($"{First.Path}/login", config =>
{
config.Run(context =>
{
context.Authentication.Challenge(new AuthenticationProperties
{ RedirectUri = First.ReturnUrl, IsPersistent = true },
"First"
);
context.Response.StatusCode = 401;
return context.Response.WriteAsync(string.Empty);
});
});
}
// Configure Second.
app.UseCookieAuthentication(Second.CookieAuthenticationOptions); // AuthenticationType is set to "Second" in these options.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
UseTokenLifetime = false,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = x => ...,
RedirectToIdentityProvider = x =>
{
var mgr = x.Options.ConfigurationManager as PolicyConfigurationManager;
if (x.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
{
var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,
x.OwinContext.Authentication.AuthenticationResponseRevoke.Properties.Dictionary["PolicyId"]);
x.ProtocolMessage.IssuerAddress = config.EndSessionEndpoint;
}
else
{
var config = await mgr.GetConfigurationByPolicyAsync(CancellationToken.None,
x.OwinContext.Authentication.AuthenticationResponseChallenge.Properties.Dictionary["PolicyId"]);
x.ProtocolMessage.IssuerAddress = config.AuthorizationEndpoint;
}
var redirectUri = Second.ReturnPath;
x.ProtocolMessage.RedirectUri = redirectUri;
x.ProtocolMessage.PostLogoutRedirectUri = redirectUri;
},
SecurityTokenValidated = x => ...
},
Scope = "openid",
ResponseType = "id_token",
ReturnUri = Second.ReturnUri,
ClientId = Second.ClientId,
ConfigurationManager = GetConfigurationManager()
AuthenticationType = configuration.AuthenticationType
});
app.Map(Second.LoginPath, config =>
{
// Trigger unauthorized so that active authentication will redirect to active directory.
config.Run(context =>
{
// Set policy in context to mitigate null ref exception in Startup.Auth OnRedirectToIdentityProvider
context.Authentication.Challenge(
new AuthenticationProperties(new Dictionary<string, string>
{
{"PolicyId", Second.LoginPolicyId}
})
{
IsPersistent = true,
RedirectUri = returnUrl
}, "Second");
context.Response.StatusCode = 401;
// Middleware will redirect us instead of using this output.
return context.Response.WriteAsync(string.Empty);
});
});
app.Map(Second.ReturnPath, config =>
{
config.Use((context, next) =>
{
// In case of login, we will never get here because we will get redirected by middleware.
context.Response.Redirect("/");
return Task.FromResult(0);
});
});
当启用First时,这允许我执行
var identity = HttpContext.Current.GetOwinContext.Authentication.AuthenticateAsync("Second").Result?.Identity;
对后续请求并具有ClaimsIdentity。但是当启用First时,由于某种原因,上述结果为空。
我注意到当我启用第一个和第二个,并将DefaultSignInAsAuthenticationType设置为“Second”时,它首先不再起作用。如果我同时启用First和Second,并使用以前的身份验证cookie浏览网站,那么一切正常。
我猜测返回方法,某处设置身份验证cookie需要一些AuthenticationType的引用,但我不知道该怎么做。
我错过了什么?
答案 0 :(得分:2)
诀窍是在配置Second时将AuthenticationType添加到TokenValidationParameters,如下所示:
String storeToDataSink (contains all the book names)
testRunner.testCase.testSteps["DataSink"].setPropertyValue("Book1",
storeToDataSink.toString())