OWIN OpenIdConnect 中间件 - 动态设置 RedirectUri

OWIN OpenIdConnect middleware - set RedirectUri dynamically

有什么方法可以根据请求范围而不是应用程序范围为 OpenIdConnectMessage 设置 RedirectUri 属性?

我的应用服务于多个域(myapp.com、myapp.fr、..),它会根据域确定内容的默认语言。我需要在通过 IdP 登录后将用户带回同一域,因此我需要找到一种方法,如何根据请求范围设置 RedirectUri,而不是通过在 startup.cs 中配置中间件选项完成的应用程序范围。

这可以通过 Notification 事件 RedirectToIdentityProvider 完成。像这样:

 Notifications = new OpenIdConnectAuthenticationNotifications
                 {
                     RedirectToIdentityProvider = async n =>
                     {
                         n.ProtocolMessage.RedirectUri = n.OwinContext.Request.Uri.Host;
                         n.ProtocolMessage.PostLogoutRedirectUri = n.OwinContext.Request.Uri.Host;
                     },
                     //other notification events...
                 }

`

如果您使用 ResponseType = OpenIdConnectResponseType.CodeIdToken,则需要在多个通知事件中设置 RedirectUri

AuthorizationCodeReceived 通知中,您可以在 TokenEndpointRequest 上设置 RedirectUri 以确保在令牌请求中也传递相同的值。

RedirectToIdentityProvider = n =>
{
    n.ProtocolMessage.RedirectUri = redirectUrl;
    // other settings   
}
AuthorizationCodeReceived = n =>
{
    n.TokenEndpointRequest.RedirectUri = redirectUrl;
    // other settings   
}

我知道这是一篇旧文章post,答案已经提到了。但是我还是花了一段时间才弄清楚如何设置动态 RedirectUri。

我在 OpenIdConnectAuthenticationOptions 和 RedirectToIdentityProvider 中分配 RedirectUri,这导致了问题。

我们应该只在 RedirectToIdentityProvider 事件中分配 RedirectUri。

需要帮助的可以查看我的代码here

当您将站点发布到 Microsoft Azure 时,多个域指向同一站点并打开:身份验证-> 允许未经身份验证的访问(您的站点有 public和私人页面); Microsoft Azure 随机回调您的重定向 URI 之一。要控制这种随机行为,您需要根据 Owin 上下文请求显式设置 RedirectUri 属性。

不要问我为什么,你还需要更改 URI 地址删除 “.auth/login/aad/callback” 除了 localhost。 (如果有人知道这个原因请告诉我)

这个代码对我有用:

    public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions());

        app.UseOpenIdConnectAuthentication(
            new OpenIdConnectAuthenticationOptions
            {
                ClientId = clientId,
                Authority = authority,
                PostLogoutRedirectUri = postLogoutRedirectUri,

                Notifications = new OpenIdConnectAuthenticationNotifications()
                {
                    AuthenticationFailed = (context) =>
                    {
                        return System.Threading.Tasks.Task.FromResult(0);
                    },
                    RedirectToIdentityProvider = (context) =>
                    {
                        string strPostLogoutRedirectUri;
                        string strRedirectUri = EnsureTrailingSlash(context.OwinContext.Request.Uri.ToString());

                        int nPos = strRedirectUri.IndexOf("://");
                        if (nPos > 0)
                        {
                            nPos += 3;
                            strPostLogoutRedirectUri = "https://" + strRedirectUri.Substring(nPos, strRedirectUri.IndexOf("/", nPos) - nPos + 1);
                            strRedirectUri = strPostLogoutRedirectUri;
                            if (strRedirectUri.Contains("localhost"))
                            {
                                strRedirectUri = strPostLogoutRedirectUri + ".auth/login/aad/callback";
                            }
                        }
                        else
                        {
                            strRedirectUri = "https://YOURSITE.com/";
                            strPostLogoutRedirectUri = "https://YOURSITE.com/";
                        }
                        context.ProtocolMessage.RedirectUri = strRedirectUri;
                        context.ProtocolMessage.PostLogoutRedirectUri = strPostLogoutRedirectUri;
                        return System.Threading.Tasks.Task.FromResult(0);
                    }
                }
            }
            );

        // This makes any middleware defined above this line run before the Authorization rule is applied in web.config
        app.UseStageMarker(PipelineStage.Authenticate);
    }

    private static string EnsureTrailingSlash(string value)
    {
        if (value == null)
        {
            value = string.Empty;
        }

        if (!value.EndsWith("/", StringComparison.Ordinal))
        {
            return value + "/";
        }

        return value;
    }