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