如何确保在 OWIN 应用程序中的 WS 联合身份验证后使用用户的原始请求 URL

How to make sure the user's original request URL is used after WS Federated authentication in OWIN app

我有一个 OWIN 应用程序,它使用 cookie 身份验证对用户进行身份验证,如果失败,它会尝试 WS-Federated 身份验证。换句话说,如果初始请求中没有正确的 cookie,则转至 STS 并获取安全令牌。

我遇到的问题是,如果使用联合身份验证,请确保满足用户最初的 URL 请求。感谢 this post, I realized that the redirect URL from the STS back to the OWIN app contains the "original" URL in the wctx query parameter. The issue is that this value is set, as far as I can tell, using WsFederationAuthenticationOptions.Wtrealm(也许 Wreply?)。这是一个问题,因为这些值是在初始配置中设置的。我不想要硬编码值——我只想要用户最初使用的 URL(即 IOwinContext.Request.Uri)。 WtrealmWreply 的文档无法帮助解释这些值应该是什么。

我以为我可以在重定向到 STS 之前偷偷将 Wtrealm 设置为用户的请求 URL,但显然它在 RedirectToIdentityProvider 通知发出时已经设置好了:

RedirectToIdentityProvider = context =>
{
    context.Options.Wtrealm = context.Request.Uri.ToString();
}

有谁知道正确的做法是什么?有没有办法让初始配置中的Wtrealm成为用户的请求URL?还是 Wtrealm 不是我想的那样,我应该以不同的方式处理这个问题?

我相信我明白了。 Wtrealm,正如我所怀疑的那样,这不是导致问题的原因;用于确定 STS 应该重新进入哪里以完成联合身份验证,但是还有另一个重定向 URL 确定身份验证后去哪里。

我使用 ILSpy 研究了 Microsoft.Owin.Security.WsFederation 源代码,发现有一个 属性 我没有设置:AuthenticationProperties.RedirectUri。此 RedirectUri 属性 需要在重定向到 STS 之前设置,因为它需要稍后在身份验证后的 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 启动 URL 是 http://myapp.com/owin. So then I set Wtrealm = "http://myapp.com/owin". Let's say a user goes to http://myapp.com/owin/coolstuff, and let's say they are signed into the authentication server with SSO, but they don't have the cookie for my app. In this case WS-Federated authentication needs to be used. 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,以便在身份验证完成后重定向。

我很确定它是这样工作的,但我可能是错的,如果有人有什么要补充的,我很乐意听听。