[英]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.