关于asp.net mvc:为什么在身份验证之前执行onAuthorization?

Why is onAuthorization executing before authentication?

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

我想对用户进行身份验证后对其进行授权。
我想念什么吗?

这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[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");
            }
        }
    }

我测试过的控制器类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class SecurityController : AuthorizationController
{

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

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

AuthorizeAttribute要做的第一件事就是检查用户是否已通过身份验证。 如果不是,那将是发出重定向到登录页面的时间。

AuthorizeAttribute基本上将认证检查和授权包装在一起:

1
2
3
4
5
6
7
8
9
protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
        if (httpContext == null) {
            throw new ArgumentNullException("httpContext");
        }

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

当您像在示例中一样使用没有角色/用户的AuthorizeAttribute时([Authorize]),在这种情况下,基本上只是检查以确保对用户进行身份验证。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 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;
            }

        }
    }

您的控制器将如下所示,

1
2
3
4
5
6
 [AuthLog(Roles ="Manager")]    
        public ActionResult Create()
        {
            var product = new Product();
            return View(product);
        }

最后创建新的共享视图。调用" AuthorizeFailed"。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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();
        }
    }

}