Атрибут Asp.net MVC Authorize, перенаправить на пользовательскую страницу «без прав» - PullRequest
31 голосов
/ 16 декабря 2010

Asp.net MVC2 перенаправляет на страницу входа с response 302, когда аутентифицированный пользователь не имеет прав.

Я хотел бы разделиться на два действия

  1. Если пользователь неАутентифицированный, затем сделайте то, что он делает, перенаправьте на страницу входа в систему.
  2. Если пользователь аутентифицирован, но не имеет необходимых прав, тогда верните соответствующий код статуса http и не показывайте страницу с чувством прав.Есть ли способ сделать это?Или я что-то не так делаю с авторизацией и аутентификацией формы?Единственный способ, о котором я могу думать, - это написать собственный атрибут авторизации, которого я хочу избежать.

Ответы [ 5 ]

19 голосов
/ 16 декабря 2010

Вы можете написать собственный атрибут фильтра следующим образом:

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
{

}
9 голосов
/ 16 декабря 2010

Вы можете написать собственный атрибут авторизации и в методе AuthorizeCore , если пользователь не аутентифицирован, вернуть HttpUnauthorizedResult и если он аутентифицирован, но не в ролях, выполните некоторые другие действия хотел бы. Обратите внимание, что если вы вернете код состояния 401, платформа FormsAuthentication в конечном итоге будет перенаправлена ​​с 302 на страницу входа.

7 голосов
/ 19 января 2012

Реализуйте пользовательский 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;
                }
            }
        }
    }
}
7 голосов
/ 15 апреля 2011

Как предлагается в Настройка авторизации в ASP.NET MVC , вы можете создать подкласс AuthorizeAttribute для перехвата аутентифицированного, но неавторизованного сценария и замены результата перенаправлением.

3 голосов
/ 01 февраля 2013

Подобно решениям, предложенным @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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...