当验证用户没有权限时,Asp.net MVC2会重定向到登录页面response 302
。Asp.net MVC授权属性,重定向到自定义“无权限”页面
我想分成两个行动
- 如果用户没有通过验证,然后做它,重定向到登录页面。
- 如果用户已通过身份验证但没有必需的权限,则返回相应的http状态码,并且不显示权利花花白页面。
有没有办法做到这一点?或者我在授权和表单身份验证方面做错了什么?我唯一能想到的方式就是编写自定义的授权属性,这是我想避免的。
当验证用户没有权限时,Asp.net MVC2会重定向到登录页面response 302
。Asp.net MVC授权属性,重定向到自定义“无权限”页面
我想分成两个行动
有没有办法做到这一点?或者我在授权和表单身份验证方面做错了什么?我唯一能想到的方式就是编写自定义的授权属性,这是我想避免的。
你可以写一个自定义的授权属性,在AuthorizeCore方法,如果用户没有通过验证回报HttpUnauthorizedResult,如果他被验证,但不执行的角色,你想一些其他的动作。请注意,如果您返回401状态码,则FormsAuthentication框架将最终使用302重定向到登录页面。
但是...你只能从AuthorizeCore返回一个布尔。你必须重写OnAuthorization以返回一个ActionResult – 2012-01-26 17:31:47
@EduardoMolteni,你可以重写'HandleUnauthorizedRequest'方法以返回你想要的结果。 – 2012-01-26 17:38:09
您可以编写自定义过滤器的属性是这样的:
public class CustomAuthorizeAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity == null || !filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl + "?returnUrl=" +
filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.RawUrl));
}
//Check user right here
if (userNotRight)
{
filterContext.HttpContext.Response.StatusCode = 302;
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
而且使用它在控制器:
[CustomAuthorize]
public class HomeController : Controller
{
}
正如Customizing authorization in ASP.NET MVC建议,你可以继承的AuthorizeAttribute拦截认证 - 丁 - 未经授权的情况,并用重定向替换结果。
这对于授权缓存结果尤其更好。 – 2012-02-26 14:41:49
执行自定义AuthorizeAttribute
并添加以下覆盖。基础知识是检查用户是否被认证但未被授权,然后重定向到你自己的“访问被拒绝”页面。希望这可以帮助!
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// Check if user is authenticated and if this action requires authorization
if (filterContext.HttpContext.User.Identity.IsAuthenticated
&& filterContext.ActionDescriptor.IsDefined(typeof(AuthorizeAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AuthorizeAttribute), true))
{
List<object> attributes = new List<object>(filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
attributes.AddRange(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
// Check all authorzation attributes
foreach (var attribute in attributes)
{
var authAttribute = attribute as AuthorizeAttribute;
if (authAttribute != null)
{
if (!filterContext.HttpContext.User.IsInRole(authAttribute.Roles))
{
// User is not authorized so redirect to our access denied error page
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "area", "" },
{ "controller", "Error" },
{ "action", "AccessDenied" }
});
break;
}
}
}
}
}
由@hellangle和@Andreas建议的解决方案类似,我用下面的代码来解决这个问题:
public class CustomizedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var userAuthInfo = GetUserAuthInfo();
if (!userAuthInfo.IsAuthenticated())
{
filterContext.Result = new RedirectResult(UrlToYourLoginPage);
return;
}
if (!userAuthInfo.IsAuthorized())
{
var result = new ViewResult {ViewName = "UnAuthorized"};
result.ViewBag.Message = "Sorry! You are not authorized to do this!";
filterContext.Result = result;
}
}
}
当然,你需要实现用户授权信息类及相关方法(GetUserAuthInfo,IsAuthenticated,IsAuthorized)根据您的具体需求。另外一个名为'UnAuthorized'的视图应该放在MVC引擎可以找到的地方。然后,它可以在一个控制器类(在@ hellangle的回答指出)或操作方法可以使用:
[CustomizedAuthorizeAttribute]
public class TargetController : Controller
{
[CustomizedAuthorizeAttribute]
public ActionResult TargetAction()
{
// Your Code
}
}
为了提供关于各种控制器类和操作方法不同的访问控制策略,实现了用于CustomizedAuthorizeAttribute构造它接受表示访问控制信息的参数,然后相应地实例化CustomizedAuthorizeAttribute类。
哈哈“没有权利的家伙”页...大声笑 – 2010-12-16 04:43:45