表单身份验证 + ASP.NET MVC 绝对 ReturnURL

发布于 2024-07-10 04:24:15 字数 338 浏览 8 评论 0原文

我在服务器 a 上有一个中央身份验证应用程序。 服务器 b 在同一域中有一个或多个应用程序需要从服务器 a 进行身份验证。 设置起来很容易,以便服务器 b 应用程序重定向到服务器 a。 让 ReturnURL 成为绝对值并不那么容易。

这就是皱纹。 服务器 b 上的消费应用程序有两个控制器,一个是公共的,一个是安全的。 如果 [authorize] 装饰被放置在公共操作(这是默认控制器)上,我会得到正确的绝对 URL。 但是,如果它在它自己的控制器中,我会得到一个相对 URL。

我可以拦截使用应用程序中的预请求事件,但我需要公开网站的某些部分,而不是整个粉碎。

有想法吗?

I have a central authentication application on server a. Server b has one or more applications on the same domain that need to authenticate from server a. It's easy enough to set it up so that the server b apps redirect out to server a. What's not so easy is getting the ReturnURL to be absolute.

Here's the wrinkle. Consuming app on server b has two controllers, one public and one secured. If the [authorize] decoration is placed on an action in the public (which is the default controller), I get the proper absolute URL. However, if its in it's own controller I get a relative URL.

I can intercept the on pre-request event in the consuming applications, but I need some parts of the site to be public, not the whole smash.

Ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

要走就滚别墨迹 2024-07-17 04:24:15

标准 AuthorizeAttribute 的工作方式是,如果请求未经身份验证,则将响应状态代码设置为 401。 这会启动默认身份验证模块对未经授权的请求的标准响应。 我假设您使用的是基于表单的身份验证,它将根据请求中的 url 构建返回 url。 在本例中,可能是相对 URL。

您可以做的一件事是,您可以实现一个 SSOAuthorizeAttribute,它扩展了 AuthorizeAttribute 类并覆盖 OnAuthorization,而不是依赖于内置行为。 然后,您可以从 Web 配置中的 forms 元素中提取 loginUrl,构建您自己的 RedirectResult,并从 AuthorizationContext 参数中的 HttpContext.Request.Url.AbsoluteUri 属性中提取 returnUrl。

 public class SSOAuthorizeAttribute : AuthorizeAttribute
 {
      public override void OnAuthorization( 
                          AuthorizationContext filterContext )
      {
          if (filterContext == null)
          {
              throw new ArgumentNullException( "filterContext" );
          }

          if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
              // get from cached variable from web configuration
              string loginUrl = ... 
              if (filterContext.HttpContext.Request != null)
              {
                  loginUrl += "?ReturnUrl=" + filterContext.HttpContext
                                                           .Request
                                                           .Url
                                                           .AbsoluteUri;
              }

              filterContext.Result = new RedirectResult( loginUrl );
          }
      }
 }

The way the standard AuthorizeAttribute works is by setting the response status code to 401 if the request is not authenticated. This kicks in the default authentication module's standard response to an unauthorized request. I assume that you're using forms-based authentication, which would build the return url based on the url in the request. In this case, probably a relative URL.

One thing you could do is instead of relying on the built-in behavior, you could implement a SSOAuthorizeAttribute which extends the AuthorizeAttribute class and overrides OnAuthorization. You could then extract the loginUrl from the forms element in the web configuration and build your own RedirectResult and pull the returnUrl from the HttpContext.Request.Url.AbsoluteUri property in the AuthorizationContext parameter.

 public class SSOAuthorizeAttribute : AuthorizeAttribute
 {
      public override void OnAuthorization( 
                          AuthorizationContext filterContext )
      {
          if (filterContext == null)
          {
              throw new ArgumentNullException( "filterContext" );
          }

          if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
              // get from cached variable from web configuration
              string loginUrl = ... 
              if (filterContext.HttpContext.Request != null)
              {
                  loginUrl += "?ReturnUrl=" + filterContext.HttpContext
                                                           .Request
                                                           .Url
                                                           .AbsoluteUri;
              }

              filterContext.Result = new RedirectResult( loginUrl );
          }
      }
 }
何时共饮酒 2024-07-17 04:24:15

假设表单身份验证,在服务器 B 应用程序 web.config 中,将 forms 标记上的 loginUrl 属性设置为控制器操作方法,该方法在重定向到服务器 A 之前附加绝对 url。

服务器 B 上的配置

<authentication mode="Forms">
  <forms loginUrl="/Account/LoginRedirect" />
</authentication>

操作方法如下所示

 public RedirectResult LoginRedirect(string returnUrl)
    {
       var requestUrl = HttpContext.Current.Request.Url;
       return LoginUrlOnServerA + 
              "?returnUrl=" +          
              HttpUtility.UrlEncode(string.Format("http://{0}:{1}{2}",
                requestUrl.Host,
                requestUrl.Port,
                HttpUtility.UrlDecode(returnUrl)));
     }

Assuming forms authentication, in the server B apps web.config, set the loginUrl attribute on the forms tag to a Controller Action method that tacks on the absolute url before redirecting to server A.

Config on server B

<authentication mode="Forms">
  <forms loginUrl="/Account/LoginRedirect" />
</authentication>

The action method would look like

 public RedirectResult LoginRedirect(string returnUrl)
    {
       var requestUrl = HttpContext.Current.Request.Url;
       return LoginUrlOnServerA + 
              "?returnUrl=" +          
              HttpUtility.UrlEncode(string.Format("http://{0}:{1}{2}",
                requestUrl.Host,
                requestUrl.Port,
                HttpUtility.UrlDecode(returnUrl)));
     }
≈。彩虹 2024-07-17 04:24:15

https://stackoverflow.com/a/583608/80589 但更短:

public RedirectResult LogOn(string returnUrl)
{
  var r = new Uri(Request.Url, returnUrl).ToString();
  return Redirect("https://logonserver.com/?return_url=" + Url.Encode(r));
}

as https://stackoverflow.com/a/583608/80589 but shorter:

public RedirectResult LogOn(string returnUrl)
{
  var r = new Uri(Request.Url, returnUrl).ToString();
  return Redirect("https://logonserver.com/?return_url=" + Url.Encode(r));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文