使用多个ADFS + Cookies时未执行OWIN Challenge()方法

时间:2015-12-02 17:03:27

标签: c# asp.net owin adfs katana

我的ASP.Net应用程序使用OWIN / Katana / Claims,并允许使用以下命令登录:

  1. 传统用户名/密码(适用于所有用户)
  2. 谷歌
  3. Azure AD
  4. 它完美运行,并且所有必要的重定向/声明传输都运行良好(用户NameIdentifier / Provider(/ tenant)详细信息将传递回我的应用程序,以便可以链接唯一的id值)。请注意,用户不会注册/注册应用程序 - 访问权限由其组织的超级用户提供,并且发送给他们的用户名/密码可以与Google / Azure联系。

    但是,我现在需要扩展此功能以允许用户连接到其组织的ADFS提供程序。远程关闭的唯一工作示例是(tutorial / code),但它严格基于ADFS。当我将其改编为我的项目时,它不起作用。

    我的整个StartupAuth文件如下所示。我很欣赏可能存在配置错误,但根据我在过去六周内发现的样本碎片,这是我所拥有的最好的。

    public void Configuration(IAppBuilder app)
        {
            // STANDARD CODE FOR APP COOKIE AND GOOGLE - WORKS PERFECTLY
    
            CookieAuthenticationOptions coa = new CookieAuthenticationOptions {
                AuthenticationMode = AuthenticationMode.Active,
                CookieName = "MyAppName",
                ExpireTimeSpan = TimeSpan.FromMinutes(60),
                SlidingExpiration = true,
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/login.aspx"),
                CookieHttpOnly = true,
                CookieSecure = CookieSecureOption.SameAsRequest,
                Provider = new CookieAuthenticationProvider { OnValidateIdentity = context =>
                {
                    dynamic ret = Task.Run(() =>
                    {
                        // Verify that "userId" and "customerId" claims exist, and that each has a valid value (greater than zero) - removed for brevity
                        return Task.FromResult(0);
                    });
                    return ret;
                } }
            };
            app.SetDefaultSignInAsAuthenticationType(coa.AuthenticationType);
            app.UseCookieAuthentication(coa);
    
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
            app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions {
                ClientId = "84***********************k3.apps.googleusercontent.com",
                ClientSecret = "jue*****************Ppi"
            });
    
    
    
            // NEW CODE THAT FAILS TO WORK - SPECIFYING EACH CUSTOMER'S ADFS AS A NEW WSFED AUTH OPTION
    
    
            WsFederation.WsFederationAuthenticationOptions Adfs_CompanyA = new WsFederation.WsFederationAuthenticationOptions {
                AuthenticationMode = AuthenticationMode.Passive,
                MetadataAddress = "https://CompanyA.net/FederationMetadata/2007-06/FederationMetadata.xml",
                AuthenticationType = AdfsAuthenticationTypes.CompanyA,
                Wtrealm = "https://www.CompanyA.co.uk/MyAppName"
            };
    
            WsFederation.WsFederationAuthenticationOptions Adfs_CompanyB = new WsFederation.WsFederationAuthenticationOptions {
                AuthenticationMode = AuthenticationMode.Passive,
                MetadataAddress = "https://CompanyB.net/federationmetadata/2007-06/federationmetadata.xml",
                AuthenticationType = AdfsAuthenticationTypes.CompanyB,
                Wtrealm = "http://www.CompanyB.co.uk/azure/MyAppName"
            };
    
            // User (who is logged in), route for hyperlink "Link my account with ADFS"
            app.Map("/SSO/LinkUserAccount/ADFS/process", configuration => { configuration.UseWsFederationAuthentication(Adfs_CompanyA); });
    
            // CompanyA ADFS - single sign-on route
            app.Map("/SSO/Login/CompanyA/ADFS/Go", configuration => { configuration.UseWsFederationAuthentication(Adfs_CompanyA); });
    
            // CompanyB ADFS - single sign-on route
            app.Map("/SSO/Login/CompanyB/ADFS/Go", configuration => { configuration.UseWsFederationAuthentication(Adfs_CompanyB); });
        }
    }
    

    以下是我用来发布OWIN挑战的代码:

    string provider = MyApp.SingleSignOn.GetCustomerAdfsAuthenticationType(customerName);
    string redirectUrl = string.Format("{0}/SSO/Login/{1}/ADFS/Go", Request.Url.GetLeftPart(UriPartial.Authority), provider); // creates https://myapp.com/SSO/Login/CompanyA/ADFS/Go for CompanyA users
    Context.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = redirectUrl }, provider);
    Response.StatusCode = 401;
    Response.End();
    

    这是webforms,但请不要让MVC专业人士停止贡献。无论如何,代码实际上是相同的,我正在使用路线。

    我遇到的问题是,当用户点击“使用ADFS登录”链接时,例如网址变为https://myapp.com/SSO/Login/CompanyA/ADFS 我收到401 Unauthorized错误,而不是用户被重定向到ADFS登录页面 在web.config中,我允许未经授权访问路径“SSO”。由于某种原因,Challenge()方法永远不会重定向用户,它只会被忽略,代码到达返回401的点。字符串provider的值与定义的WsFederationAuthenticationOptions.AuthenticationType值完全匹配在Startup.Auth。

    我现在已经熬了六个星期了,所以这是第一次获得赏金,并且在解决之后将一箱啤酒送到您选择的地址。

2 个答案:

答案 0 :(得分:4)

我解决了这个问题。令人惊讶的是,它就像我在StartupAuth结束时一样简单:

app.UseStageMarker(PipelineStage.Authenticate);

答案 1 :(得分:0)

您是否设置了OWIN日志记录?那里有任何线索吗?

Test driving the WS-Federation Authentication Middleware for Katana

查看IdentityServer 3中的代码。那里有一个WS-Fed插件,文档是here(在底部)。