asp.net-mvc Asp.net MVC Authorize 属性,重定向到自定义“无权限”页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4457476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Asp.net MVC Authorize attribute, redirect to custom "no rights" page
提问by mamu
Asp.net MVC2 does redirect to login page with response 302
when authenticated user has no rights.
response 302
当经过身份验证的用户没有权限时,Asp.net MVC2 会重定向到登录页面。
I would like to split into two actions
我想分成两个动作
- If user is not authenticated then do what it does, redirect to login page.
- If user is authenticated but has no required rights then return appropriate http status code and show no rights dude page.
- 如果用户未通过身份验证,则执行它所做的操作,重定向到登录页面。
- 如果用户已通过身份验证但没有所需的权限,则返回适当的 http 状态代码并显示没有权限的页面。
Is there any way to do it? Or am I doing something wrong with authorize and form authentication? Only way I can think of is by writing custom authorize attribute, which I want to avoid.
有什么办法吗?或者我在授权和表单身份验证方面做错了什么?我能想到的唯一方法是编写自定义授权属性,我想避免这种情况。
回答by hellangle
You could write custom filter attribute like this:
您可以像这样编写自定义过滤器属性:
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();
}
}
}
And use it in controller:
并在控制器中使用它:
[CustomAuthorize]
public class HomeController : Controller
{
}
回答by Darin Dimitrov
You could write a custom authorize attribute and in the AuthorizeCoremethod if the user is not authenticated return a HttpUnauthorizedResultand if he is authenticated but not in roles perform some other action you would like. Note that if you return 401 status code the FormsAuthentication framework will eventually redirect with 302 to the login page.
您可以编写自定义授权属性,如果用户未通过身份验证,则在AuthorizeCore方法中返回HttpUnauthorizedResult,如果他已通过身份验证但不在角色中,则执行您想要的其他一些操作。请注意,如果您返回 401 状态代码,FormsAuthentication 框架最终将使用 302 重定向到登录页面。
回答by Brian Rogers
As suggested in Customizing authorization in ASP.NET MVC, you could subclass the AuthorizeAttribute to intercept the authenticated-but-unauthorized scenario and replace the result with a redirect.
正如在 ASP.NET MVC中自定义授权中所建议的,您可以将 AuthorizeAttribute 子类化以拦截已验证但未授权的场景,并将结果替换为重定向。
回答by Andreas
Implement a custom AuthorizeAttribute
and add the following override. The basics is to check if user is authenticated but not authorized and then redirect to you own "Access Denied" page. Hope this helps!
实现自定义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;
}
}
}
}
}
回答by wiser
Similar to solutions suggested by @hellangle and @Andreas, I used the following code to solve this problem:
与@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;
}
}
}
Of course, you need to implement the user authorization information class and related methods (GetUserAuthInfo, IsAuthenticated, IsAuthorized) according to your specific needs. Also a View named 'UnAuthorized' should be put to somewhere the MVC engine can find. Then it can be used on a controller class (pointed out in @hellangle's answer) or a action method:
当然,您需要根据自己的具体需求实现用户授权信息类及相关方法(GetUserAuthInfo、IsAuthenticated、IsAuthorized)。此外,一个名为“UnAuthorized”的视图应该放在 MVC 引擎可以找到的地方。然后它可以用于控制器类(在@hellangle 的回答中指出)或操作方法:
[CustomizedAuthorizeAttribute]
public class TargetController : Controller
{
[CustomizedAuthorizeAttribute]
public ActionResult TargetAction()
{
// Your Code
}
}
In order to provide different access control strategy for various controller classes and action methods, implements a constructor for CustomizedAuthorizeAttribute class which accepts parameter(s) representing access control information and then Instantiate CustomizedAuthorizeAttribute class accordingly.
为了为各种控制器类和动作方法提供不同的访问控制策略,为 CustomizedAuthorizeAttribute 类实现一个构造函数,该类接受表示访问控制信息的参数,然后相应地实例化 CustomizedAuthorizeAttribute 类。