ASP.NET Web窗体站点 - 使用OWIN KATANA与多个ADFS集成

时间:2016-10-12 12:51:02

标签: asp.net webforms owin ws-federation adfs3.0

我正在将旧的现有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中间件成功,无论哪一个。我还尝试将中间件附加到不同的管道阶段,但没有成功。

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

对于多个wsfed中间件,每个应该设置一个唯一的WsFederationAuthenticationOptions.CallbackPath,例如: “/ WS1”。您还需要在wreply中包含此值。

答案 1 :(得分:0)

我只是为@Tratcher建议的解决方案提供更多细节,以保持问题简洁明了:

1)According to MSDNCallbackPath如果未设置则从Wreply计算;

2)在为每个提供商区分Wreply之后,结果证明这还不够,因为出现了其他问题。然后我发现(使用我的MVC工作样本),WtrealmWreply应具有相同的值;

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(...)添加每个中间件似乎没问题!