asp.net-mvc 为什么在认证之前执行 onAuthorization?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9366085/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:45:05  来源:igfitidea点击:

Why is onAuthorization executing before authentication?

asp.net-mvcauthenticationauthorization

提问by misha

I'm trying to do some custom authorization so I created a controller overriding the OnAuthorizationmethod. I also applied the Authorizeattribute to this controller. The question is why is the OnAuthorizationmethod called BEFORE the basic forms authentication process?

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

I would like to authorize the user after he is authenticated. Am I missing something?

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

Here is the code:

这是代码:

[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");
            }
        }
    }

The controller that I tested with is something like:

我测试的控制器类似于:

public class SecurityController : AuthorizationController
{

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

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

回答by Dismissile

One of the first things the AuthorizeAttributedoes is check to see if the user is authenticated. If they are not then that is when a redirect to the login page will be issued.

首先要做的事情之一AuthorizeAttribute是检查用户是否已通过身份验证。如果不是,则将发出重定向到登录页面的消息。

The AuthorizeAttributebasically wraps the authentication check in with the authorization piece:

AuthorizeAttribute基本包装认证检查与授权件:

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

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

When you use the AuthorizeAttribute with no roles/users as you do in your example ([Authorize]), it is basically just checking to make sure the user is authenticated in this case.

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

I would probably change your code to override the AuthorizeAttribute instead of doing this code in your controller. You can do the following:

我可能会更改您的代码以覆盖 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)
        };
    }
}

回答by Manoj Weerasooriya

Following is a sample for Custom Authorization Attribute.

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

 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;
            }

        }
    }

Your Controller will be like following,

您的控制器将如下所示,

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

Finally create new Shared view Call "AuthorizeFailed".

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

回答by lalan kumar

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();
        }
    }

}