为什么在授权之前执行onAuthorization?

时间:2012-02-20 18:03:02

标签: asp.net-mvc authentication authorization

我正在尝试进行一些自定义授权,因此我创建了一个覆盖OnAuthorization方法的控制器。我还将Authorize属性应用于此控制器。 问题是为什么OnAuthorization方法被称为BEFORE基本表单身份验证过程?

我想在用户通过身份验证后授权该用户。 我错过了什么吗?

以下是代码:

[Authorize]
    public class AuthorizationController : Controller
    {
        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            List<string> allowedControllers = new List<string>() { "SecurityController" };
            List<string> allowedActions = new List<string>() { "Index" };

            string controllerName = filterContext.Controller.GetType().Name;
            string actionName = filterContext.ActionDescriptor.ActionName;

            if (!allowedControllers.Contains(controllerName)
            || !allowedActions.Contains(actionName))
            {
                filterContext.Result = View("UnauthorizedAccess");
            }
        }
    }

我测试的控制器类似于:

public class SecurityController : AuthorizationController
{

    public ActionResult Index()
    {
        return View();
    }

    public ActionResult AnotherIndex()
    {
        return View();
    }
}

3 个答案:

答案 0 :(得分:16)

AuthorizeAttribute做的第一件事就是检查用户是否经过身份验证。如果不是那样的话,就会发出重定向到登录页面。

AuthorizeAttribute基本上使用授权部分包装身份验证检查:

protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
        if (httpContext == null) {
            throw new ArgumentNullException("httpContext");
        }

        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated) {
            return false;
        }

当您使用AuthorizeAttribute但没有像您的示例那样使用角色/用户时([授权]),基本上只是检查以确保用户在这种情况下经过身份验证。

我可能会更改您的代码以覆盖AuthorizeAttribute而不是在您的控制器中执行此代码。您可以执行以下操作:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        filterContext.Result = CreateResult(filterContext);
    }

    protected ActionResult CreateResult(AuthorizationContext filterContext)
    {
        var controllerContext = new ControllerContext(filterContext.RequestContext, filterContext.Controller);
        var controller = (string)filterContext.RouteData.Values["controller"];
        var action = (string)filterContext.RouteData.Values["action"];
        // any custom model here
        var model = new UnauthorizedModel(); 

        // custom logic to determine proper view here - i'm just hardcoding it
        var viewName = "~/Views/Shared/Unauthorized.cshtml"; 

        return new ViewResult
        {
            ViewName = viewName,
            ViewData = new ViewDataDictionary<UnauthorizedModel>(model)
        };
    }
}

答案 1 :(得分:2)

以下是自定义授权属性的示例。

 public class AuthLogAttribute:AuthorizeAttribute
    {

        public string View { get; set; }

        public AuthLogAttribute()
        {
            View = "AuthorizeFailed";
        }
        public override void OnAuthorization(AuthorizationContext filterContext)

        {
            base.OnAuthorization(filterContext);
            IsUserAuthorized(filterContext);
        }

        private void IsUserAuthorized(AuthorizationContext filterContext)
        {
            // If the Result returns null then the user is Authorized 
            if(filterContext.Result ==null)
                return;

            //If the user is Un-Authorized then Navigate to Auth Failed View 
            if(filterContext.HttpContext.User.Identity.IsAuthenticated)

            {
                var vr = new ViewResult();
                vr.ViewName = View;

                ViewDataDictionary dict = new ViewDataDictionary();
                dict.Add("Message", "Sorry you are not Authorized to Perform this Action");
                vr.ViewData = dict;

                var result = vr;
                filterContext.Result = vr;
            }

        }
    }

您的控制器将如下,

 [AuthLog(Roles ="Manager")]     
        public ActionResult Create()
        {
            var product = new Product();
            return View(product);
        }

最后创建新的共享视图Call&#34; AuthorizeFailed&#34;。

答案 2 :(得分:-2)

public override void OnAuthorization(AuthorizationContext filterContext)
{
    base.OnAuthorization(filterContext);
    bool flag = false;
    string UserId;
    string[] AssignedRights = null;

    //Check if Http Context Contains User Name
    if (HttpContext.Current.User.Identity.Name != null && HttpContext.Current.User.Identity.Name != string.Empty)
    {
        //Get User Id from HttpContext
        UserId = HttpContext.Current.User.Identity.Name;
        RoleRepository roleRepository = new RoleRepository();
        AssignedRights = roleRepository.GetRolesByUser(Convert.ToInt32(UserId));
        flag = IsUserAuthorized(filterContext, flag, AssignedRights);

        if (flag == false)
       {

           filterContext.Result = new HttpUnauthorizedResult();
        }
    }

}