簡體   English   中英

表單身份驗證+ ASP.NET MVC絕對ReturnURL

[英]Forms authentication + ASP.NET MVC absolute ReturnURL

我在服務器a上有一個中央身份驗證應用程序。 服務器b在同一域上具有一個或多個需要從服務器a進行身份驗證的應用程序。 設置起來很容易,以便服務器b應用重定向到服務器a。 要使ReturnURL成為絕對值不是那么容易。

這是皺紋。 服務器b上的消費應用程序具有兩個控制器,一個為公共控制器,另一個為安全控制器。 如果將[authorize]裝飾放在公眾的某個動作上(這是默認控制器),我將獲得正確的絕對URL。 但是,如果它在它自己的控制器中,則會得到一個相對URL。

我可以在使用中的應用程序中攔截請求前事件,但是我需要使網站的某些部分公開,而不是整個粉碎。

有想法嗎?

標准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 );
          }
      }
 }

假設進行表單身份驗證,請在服務器B應用程序web.config中,將Forms標記上的loginUrl屬性設置為Controller Action方法,該方法在重定向到服務器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)));
     }

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));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM