我正在将旧的现有Web表单站点配置为多租户环境。一个要求是能够与多个客户端ADFS集成。
我已经关注this post并成功实现了支持多个ADFS的MVC应用程序。但是我还是面临一个问题,
这与MVC应用程序无法重现。在我的Web表单站点中,只有第一个ADFS提供程序注册成功。第二个永远
在验证并返回我的站点后抛出SignatureVerificationFailedException(异常发生在我身边)。
这不管我是否在OWIN启动配置中使用app.Map(...)或app.Use(...)。
我尝试将我的网站转换为Web应用程序,但结果相同。我想这与WEB FORMS中处理请求的方式有关,这与MVC不同。
我应该以某种不同的方式处理中间件映射吗?
我错过了什么?
或者根本不可能这样做?...
这是我的OWIN启动配置:
app.Properties["Microsoft.Owin.Security.Constants.DefaultSignInAsAuthenticationType"] = Config.ExternalAuthentication.Cookie;
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = Config.ExternalAuthentication.Cookie,
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive
});
string wreply = Config.ExternalAuthentication.Wreply;
string wtrealm = Config.ExternalAuthentication.Wtrealm;
List<Company> adfsCompanies = BL.GetCompaniesWithADFS();
app.Map("/Public/Login.aspx", configuration =>
{
foreach (Company company in adfsCompanies)
{
//configure middleware
var middleware = new WsFederationAuthenticationOptions()
{
MetadataAddress = company.ADFSMetadataUrl,
AuthenticationType = company.TenantName,
Caption = company.Name,
Wreply = wreply,
Wtrealm = wtrealm,
BackchannelCertificateValidator = null
};
//add to pipeline
configuration.UseWsFederationAuthentication(middleware);
}
});
这是我的挑战请求:
context.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties { RedirectUri = callbackUrl },
provider);
response.StatusCode = 401;
response.End();
无论我做什么,只有第一个注册的ADFS中间件成功,无论哪一个。我还尝试将中间件附加到不同的管道阶段,但没有成功。
提前感谢您的帮助!
答案 0 :(得分:1)
对于多个wsfed中间件,每个应该设置一个唯一的WsFederationAuthenticationOptions.CallbackPath,例如: “/ WS1”。您还需要在wreply中包含此值。
答案 1 :(得分:0)
我只是为@Tratcher建议的解决方案提供更多细节,以保持问题简洁明了:
1)According to MSDN,CallbackPath
如果未设置则从Wreply
计算;
2)在为每个提供商区分Wreply
之后,结果证明这还不够,因为出现了其他问题。然后我发现(使用我的MVC工作样本),Wtrealm
和Wreply
应具有相同的值;
3)在ASP.NET Web Forms中为不同的提供程序设置不同的URL结果并不那么容易。虚假网址无效。使用URL重写 - 也。
最直接的解决方案是为每个提供者使用不同的回调页面(例如,ExternalLoginFirstADFS.aspx,ExternalLoginSecondADFS.aspx,...)。这虽然工作正常,但并不是最好的,所以我决定在Global.asax的Application_Start
事件中为每个提供者配置一条路由,如下所示:
void Application_Start(object sender, EventArgs e)
{
...
RegisterRoutes(System.Web.Routing.RouteTable.Routes);
}
public static void RegisterRoutes(System.Web.Routing.RouteCollection routes)
{
List<Organization> adfsCompanies = OrgElementEntity.GetCompaniesWithADFS();
foreach(Organization company in adfsCompanies)
{
routes.MapPageRoute("",
String.Format("Public/ExternalLogin{0}.aspx", company.TenantName),
"~/Public/ExternalLogin.aspx");
}
}
此外,事实证明,app.Map(...)
无需使用OwinStartup
。只需通过app.UseWsFederationAuthentication(...)
添加每个中间件似乎没问题!