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

ASP.NET Web Forms Site - integration with multiple ADFS using OWIN KATANA

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

在此先感谢您的帮助!

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

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

1) According to MSDN, CallbackPath 如果没有设置则从Wreply计算;

2) 在为每个提供者区分 Wreply 之后发现这还不够,因为出现了其他问题。然后我发现(使用我的 MVC 工作示例)此外 WtrealmWreply 应该具有相同的值;

3) 在 ASP.NET Web Forms 中为不同的提供者设置不同的 URLs 原来不是那么容易。假 URLs 不起作用。使用 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");
    }
}

此外,事实证明在OwinStartup处也没有必要使用app.Map(...)。通过 app.UseWsFederationAuthentication(...) 添加每个中间件似乎没问题!