【问题标题】:OWIN OpenIdConnect middleware - set RedirectUri dynamicallyOWIN OpenIdConnect 中间件 - 动态设置 RedirectUri
【发布时间】:2015-08-19 03:26:56
【问题描述】:

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

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

【问题讨论】:

    标签: owin middleware openid-connect


    【解决方案1】:

    这可以通过 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...
                     }
    

    `

    【讨论】:

    • 你救了我,我完全忘记了事件。我必须动态更改 clientId。
    • 我知道这是一个老问题,但我正在开发一个旧的 .NET 框架 4.7.2 应用程序。我正在尝试使用这种方法在 RedirectToIdentityProvider 中动态设置RedirectUri,但它会导致异常Error: 'invalid_grant'. Error_Description (may be empty): 'Incorrect redirect_uri'. 但是,如果我只在OpenIdConnectAuthenticationOptions 中的应用程序启动时设置RedirectUrl 属性,它就可以正常工作。我在网上找不到任何其他参考来更改导致此问题的 RedirectUri。有什么建议吗?
    • 对于任何阅读 Chris 上述评论的人来说,请注意:此错误来自身份提供者,因此这意味着应用程序和 IdP 未配置为接受 HTTP 请求中传递的 redirect_url 参数和流程的开始。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

      • 非常感谢。这解决了我的问题。
      【解决方案4】:

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

      不要问我为什么,你还需要更改 URIs 地址删除 “.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;
          }
      

      【讨论】:

        猜你喜欢
        • 2019-03-28
        • 2014-08-16
        • 2017-01-17
        • 2017-11-11
        • 2021-10-11
        • 2018-06-13
        • 1970-01-01
        • 2018-12-22
        • 2017-09-29
        相关资源
        最近更新 更多