简体   繁体   English

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

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

I'm configuring an old existing web forms site as a multi-tenant environment. 我正在将一个旧的现有Web表单网站配置为多租户环境。 One requirement is to be able to integrate with multiple client ADFS. 一项要求是能够与多个客户端ADFS集成。 I have followed this post and have successfully implemented an MVC application supporting multiple ADFS. 我已经关注了这篇文章 ,并成功实现了支持多个ADFS的MVC应用程序。 However I still face an issue, that is not reproducible with the MVC app. 但是,我仍然面临一个问题,该问题无法通过MVC应用程序重现。 In my web forms site, only the first ADFS provider registered succeeds. 在我的网站表单网站上,只有第一个注册的ADFS提供程序成功。 The second one always throws SignatureVerificationFailedException after authenticating and returning back to my site (the exception happens at my side). 第二个总是在进行身份验证并返回我的站点后抛出SignatureVerificationFailedException(异常发生在我这一边)。 This is no matter whether I use app.Map(...) or app.Use(...) in the OWIN startup configuration. 不管我是在OWIN启动配置中使用app.Map(...)还是app.Use(...)。
I tried converting my web site to web application, but same result. 我尝试将网站转换为Web应用程序,但结果相同。 I guess it is something connected with the way requests are handled in WEB FORMS, which is different than MVC. 我想这与WEB FORMS中处理请求的方式有关,这与MVC不同。

Should I handle the middleware mapping in some different way? 我应该以不同的方式处理中间件映射吗?
What am I missing? 我想念什么?
Or this is not possible at all?... 还是根本不可能?...

Here is my OWIN startup configuration: 这是我的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);
    }
});

Here is my challenge request: 这是我的挑战请求:

context.GetOwinContext().Authentication.Challenge(
    new AuthenticationProperties { RedirectUri = callbackUrl },
    provider);
response.StatusCode = 401;
response.End();

No matter what I do, only the first registered ADFS middleware succeeds, no matter which one. 无论我做什么,无论哪个,只有第一个注册的ADFS中间件都能成功。 I also tried attaching the middlewares to different pipeline stages with no success. 我还尝试将中间件附加到不同的管道阶段,但没有成功。

Thanks in advance for any help! 在此先感谢您的帮助!

For multiple wsfed middleware each should set a unique WsFederationAuthenticationOptions.CallbackPath, eg "/ws1". 对于多个wsfed中间件,每个中间件应设置一个唯一的WsFederationAuthenticationOptions.CallbackPath,例如“ / ws1”。 You'll also need to include this value in the wreply. 您还需要在wreply中包括该值。

I'm just giving some more details to the solution suggested by @Tratcher, in order to keep the question clean and simple: 我只是给@Tratcher建议的解决方案提供更多细节,以使问题保持​​简洁:

1) According to MSDN , CallbackPath if not set is calculated from Wreply ; 1) 根据MSDNCallbackPath如果未设置)是从Wreply计算的;

2) after distinguishing Wreply for each provider it turned out that was not enough, because other problems appeared. 2)在为每个提供者区分Wreply之后,结果还不够,因为出现了其他问题。 Then I found (using my MVC working sample) that furthermore Wtrealm and Wreply should have the same value; 然后,我(使用我的MVC工作样本)发现WtrealmWreply应该具有相同的值;

3) Setting different URLs for different providers in ASP.NET Web Forms turned out to not be so easy. 3)事实证明,在ASP.NET Web窗体中为不同的提供程序设置不同的URL并不容易。 Fake URLs did not work. 伪造的网址无效。 Using URL Rewrite - also. 使用URL重写-也。
The most straightforward solution is to use different callback page for each provider (eg ExternalLoginFirstADFS.aspx, ExternalLoginSecondADFS.aspx, ...). 最直接的解决方案是为每个提供程序使用不同的回调页面(例如,ExternalLoginFirstADFS.aspx,ExternalLoginSecondADFS.aspx等)。 This, although working fine, is not the best, so I decided to configure a Route for each provider at Application_Start event in Global.asax like this: 尽管可以正常工作,但这并不是最好的,所以我决定在Global.asax的Application_Start事件中为每个提供Application_Start配置一个Route,如下所示:

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");
    }
}

Furthermore, it turned out that there is no need too use app.Map(...) at OwinStartup . 此外,事实证明,在OwinStartup也不需要使用app.Map(...) Just adding each middleware through app.UseWsFederationAuthentication(...) seems to be fine! 只需通过app.UseWsFederationAuthentication(...)添加每个中间件就可以了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM