使用多个 ADFS + Cookie 时未执行 OWIN Challenge() 方法
OWIN Challenge() method not executed when using multiple ADFS + Cookies
我的 ASP.Net 应用程序使用 OWIN/Katana/Claims,并允许使用以下方式登录:
- 传统username/password(所有用户都存在)
- Google
- Azure 广告
它完美运行,所有必要的 redirects/claims 传输都运行良好(用户 NameIdentifier/Provider(/tenant) 详细信息被传回我的应用程序,因此唯一 ID 值可以是 link 向上)。请注意,用户不会为该应用程序签名 up/register - 访问权限由其组织的超级用户提供,并向他们发送 username/password,然后他们可以与 Google/Azure 连接。
但是,我现在需要扩展此功能以允许用户连接到他们组织的 ADFS 提供程序。远程关闭的唯一工作示例在此处 (tutorial/code),但它严格基于 ADFS-only。当我把它应用到我的项目中时,它不起作用。
我的整个 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();
这是网络表单,但请不要让它阻止 MVC 专业人员的贡献。无论如何,代码实际上是相同的,我正在使用路由。
我遇到的问题是,当用户点击 "sign-on with ADFS" link 时,例如URL 变为 https://myapp.com/SSO/Login/CompanyA/ADFS
我收到 401 Unauthorized 错误,而不是将用户重定向到 ADFS 登录页面。
在 web.config 中,我允许未经授权访问路径 "SSO"。由于某种原因,Challenge()
方法从不重定向用户,它只是被忽略并且代码到达它 returns 401 的位置。字符串 provider
的值与 WsFederationAuthenticationOptions.AuthenticationType
中定义的值 Startup.Auth.
我已经为此苦苦挣扎了六个星期,所以这是第一时间获得赏金,解决后一箱啤酒会送到您选择的地址。
您是否设置了 OWIN 日志记录?有什么线索吗?
还有Test driving the WS-Federation Authentication Middleware for Katana.
查看 IdentityServer 3. There's a WS-Fed plugin there and the documentation is here(底部)中的代码。
我解决了这个问题。令人惊讶的是,就像我在 StartupAuth 的末尾遗漏了这个一样简单:
app.UseStageMarker(PipelineStage.Authenticate);
我的 ASP.Net 应用程序使用 OWIN/Katana/Claims,并允许使用以下方式登录:
- 传统username/password(所有用户都存在)
- Azure 广告
它完美运行,所有必要的 redirects/claims 传输都运行良好(用户 NameIdentifier/Provider(/tenant) 详细信息被传回我的应用程序,因此唯一 ID 值可以是 link 向上)。请注意,用户不会为该应用程序签名 up/register - 访问权限由其组织的超级用户提供,并向他们发送 username/password,然后他们可以与 Google/Azure 连接。
但是,我现在需要扩展此功能以允许用户连接到他们组织的 ADFS 提供程序。远程关闭的唯一工作示例在此处 (tutorial/code),但它严格基于 ADFS-only。当我把它应用到我的项目中时,它不起作用。
我的整个 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();
这是网络表单,但请不要让它阻止 MVC 专业人员的贡献。无论如何,代码实际上是相同的,我正在使用路由。
我遇到的问题是,当用户点击 "sign-on with ADFS" link 时,例如URL 变为 https://myapp.com/SSO/Login/CompanyA/ADFS
我收到 401 Unauthorized 错误,而不是将用户重定向到 ADFS 登录页面。
在 web.config 中,我允许未经授权访问路径 "SSO"。由于某种原因,Challenge()
方法从不重定向用户,它只是被忽略并且代码到达它 returns 401 的位置。字符串 provider
的值与 WsFederationAuthenticationOptions.AuthenticationType
中定义的值 Startup.Auth.
我已经为此苦苦挣扎了六个星期,所以这是第一时间获得赏金,解决后一箱啤酒会送到您选择的地址。
您是否设置了 OWIN 日志记录?有什么线索吗?
还有Test driving the WS-Federation Authentication Middleware for Katana.
查看 IdentityServer 3. There's a WS-Fed plugin there and the documentation is here(底部)中的代码。
我解决了这个问题。令人惊讶的是,就像我在 StartupAuth 的末尾遗漏了这个一样简单:
app.UseStageMarker(PipelineStage.Authenticate);