我有一个OWIN应用程序,使用cookie身份验证对用户进行身份验证,如果失败则会尝试WS-Federated身份验证。换句话说,如果初始请求中没有正确的cookie,则转到STS并获取安全令牌。
我遇到的问题是如果使用联合身份验证,则确保满足用户的原始URL请求。感谢this post,我意识到从STS到OWIN应用的重定向网址包含"原始" wctx查询参数中的URL。问题是,据我所知,使用WsFederationAuthenticationOptions.Wtrealm
(也许Wreply
?)设置此值。这是一个问题,因为这些值是在初始配置中设置的。我不想要硬编码值 - 我只想要用户最初使用的网址(即IOwinContext.Request.Uri
)。 Wtrealm
和Wreply
的文档无法解释这些值应该是什么。
我认为在重定向到STS之前我可以偷偷地将Wtrealm
设置为用户的请求网址,但显然已经在RedirectToIdentityProvider
次通知时设置了RedirectToIdentityProvider = context =>
{
context.Options.Wtrealm = context.Request.Uri.ToString();
}
:
Wtrealm
有谁知道正确的做法是什么?有没有办法在初始配置中使用Wtrealm
用户的请求URL?或{{1}}不是我认为的那样,我应该以不同的方式接近这个?
答案 0 :(得分:1)
我相信我明白了。我怀疑Wtrealm
并不是造成这个问题的原因;用于确定STS应重新输入以完成联合身份验证的位置,但还有另一个重定向URL确定身份验证后的去向。
我使用ILSpy挖掘了Microsoft.Owin.Security.WsFederation
源代码,我发现有一个我没有设置的属性:AuthenticationProperties.RedirectUri
。在重定向到STS之前需要设置此RedirectUri
属性,因为它需要在稍后在InvokeAsync
中进行身份验证后使用。我有一个AuthenticateAllRequests
方法,我在那里初始化了这个AuthenticationProperties
对象:
private static void AuthenticateAllRequests(IAppBuilder app, params string[] authenticationTypes)
{
app.Use((context, continuation) =>
{
if (context.Authentication.User?.Identity?.IsAuthenticated ?? false)
{
return continuation();
}
else
{
AuthenticationProperties authProps = new AuthenticationProperties
{
RedirectUri = context.Request.Uri.ToString()
};
context.Authentication.Challenge(authProps, WsFederationAuthenticationDefaults.AuthenticationType);
return Task.CompletedTask;
}
});
}
更具体地总结一下:假设我的OWIN启动网址为http://myapp.com/owin。那么我设置Wtrealm = "http://myapp.com/owin"
。假设用户转到http://myapp.com/owin/coolstuff,让我们说他们已经使用SSO登录到身份验证服务器,但他们没有我的应用程序的cookie。在这种情况下,需要使用WS-Federated身份验证。 http://myapp.com/owin/coolstuff在重定向到STS之前设置为AuthenticationProperties.RedirectUri
,以便将其放入wctx
查询参数中,因此可以在返回OWIN应用程序后使用。
之前我感到困惑,因为从STS返回后,我会看到IOwinRequest.Uri = "http://myapp.com/owin"
,我认为这是最终的URL,并且用户的原始请求已丢失。现在更有意义的是,这是STS重定向到的URL以完成身份验证,但最终的重定向URL http://myapp.com/owin/coolstuff被存储用于在身份验证完成后重定向。
我很确定这是它的工作方式,但我可能错了,如果有人有任何补充,我很乐意听到。