我们的Mvc/WebAPI解决方案目前有四个受信任的身份提供程序,我们已在ADFS3中注册。这些身份提供者中的每一个都可以由我们的用户通过直接链接使用,有效地处理ADFS可能创建的任何家庭领域cookie(例如:www.ourportal.com/accounts/facebook或www.ourportal.com/saccounts/twitter)。目前,我们正在从WIF迁移到OWIN,但通过实现wsfederation和cookie身份验证中间件,暂时将继续使用WS-Federation协议。在使用WIF时,我们做了以下操作,以便直接转到已知的身份提供商:
var signInRequest = new SignInRequestMessage(stsUrl, realm) { HomeRealm = homeRealm };
return new RedirectResult(signInRequest.WriteQueryString());
这似乎有两个相关的行为,它不传递WsFedOwinState参数,并且在返回给依赖方时,在Owin身份验证中间件启动之前构建Home.cshtml(使用windows主体)。在Owin中间件之前激发的Home.cshtml是最令人担忧的,因为此视图依赖于身份验证管道完成的转换中提供的声明,而身份验证管道在之后激发,因此我们的视图不起作用。以正常方式访问门户时,它按正确的顺序工作(例如www.ourportal.com)
我知道,为了提供Whr参数,在配置ws-federation中间件时需要执行以下操作:
RedirectToIdentityProvider = (context) =>
{
context.ProtocolMessage.Whr = "SomeUrnOfAnIdentityProvider";
return Task.FromResult(0);
}
但这为整个解决方案设置了一个单一的身份提供者,并且不允许我们的用户直接转到身份提供者列表中的一个。
构建登录请求的非工作方法目前是:
private RedirectResult FederatedSignInWithHomeRealm(string homeRealm)
{
var stsUrl = new Uri(ConfigurationManager.AppSettings["ida:Issuer"]);
string realm = ConfigurationManager.AppSettings["ida:Audience"];
var signInRequest = new SignInRequestMessage(stsUrl, realm)
{
HomeRealm = homeRealm
};
HttpContext.Request.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
return new RedirectResult(signInRequest.WriteQueryString());
}
ws-federation和cookie中间件被配置为OWIN启动中的第一个中间件,默认身份验证设置为应用程序。SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
我想我找到了一个解决方案。跳过主领域屏幕的新方法如下:
private void FederatedSignInWithHomeRealm(string homeRealm)
{
HttpContext.Request
.GetOwinContext()
.Authentication
.SignOut(CookieAuthenticationDefaults.AuthenticationType);
var authenticationProperties = new AuthenticationProperties { RedirectUri = "/" };
authenticationProperties.Dictionary.Add("DirectlyToIdentityProvider", homeRealm);
HttpContext.GetOwinContext().Authentication.Challenge(authenticationProperties);
}
OWIN WS-Federation中间件的配置如下:
app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
{
Notifications = new WsFederationAuthenticationNotifications()
{
RedirectToIdentityProvider = notification =>
{
string homeRealmId = null;
var authenticationResponseChallenge = notification.OwinContext
.Authentication
.AuthenticationResponseChallenge;
var setIdentityProvider = authenticationResponseChallenge != null
&& authenticationResponseChallenge.Properties
.Dictionary
.TryGetValue("DirectlyToIdentityProvider", out homeRealmId);
if (setIdentityProvider)
{
notification.ProtocolMessage.Whr = homeRealmId;
}
return Task.FromResult(0);
}
},
MetadataAddress = wsFedMetadata,
Wtrealm = realm,
SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
TokenValidationParameters = new TokenValidationParameters
{
ValidAudience = realm
}
});