覆盖授权属性

Overriding Authorize Attribute

我需要覆盖授权属性。

基本上,如果它是一个 ajax 请求并且用户未登录或不在指定角色中,那么我想 return 一个 JSON。 JSON 将告诉呼叫者未登录或未担任角色的原因,需要 return 重定向到 url。如果没有签名,还需要返回ReturnUrl。

如果它不是 ajax 请求,那么我希望通过 Authorize 属性启动默认处理。

我们正在使用表单身份验证,登录 url 和错误页面在 web.config 文件中指定。

以下是我的看法,但我没有正确理解以下内容

  1. 在 ajax 请求的情况下缺少角色处理

  2. 如果不是 ajax 请求(else 块),我会将用户重定向到登录页面。在这种情况下,我希望启动默认的 autorize 属性

我只需要朝着正确的方向推动...教程或博客指针就是我学习和完成此任务所需的全部....

public class AuthorizePartnerProgramsAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            HttpContext httpContext = HttpContext.Current;


            var url = new UrlHelper(filterContext.RequestContext);

            var request = filterContext.HttpContext.Request;

            if (request.IsAuthenticated == false)
            {

                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    if (request.Url != null)
                        filterContext.Result = CommonUtilities.AddJsonUtf8Encoding(new JsonResult { Data = new { error = true, singinerror = true, message = "Sign in required!", returnUrl = request.UrlReferrer.AbsolutePath.ToString() } });
                    else
                        filterContext.Result = CommonUtilities.AddJsonUtf8Encoding(new JsonResult { Data = new { error = true, singinerror = true, message = "Sign in required!" } });
                }
                else
                {
                    if (request.UrlReferrer != null)
                    {
                        filterContext.Result = new RedirectResult(url.Action("Index", "SignIn", new { Area = "Account",  ReturnUrl = filterContext.RequestContext.HttpContext.Request.UrlReferrer.AbsolutePath.ToString() }));
                    }
                    else
                    {
                        filterContext.Result = new RedirectResult(url.Action("Index", "SignIn", new { Area = "Account"}));

                    }
                }

            }

        }


    }

这是我的第二次尝试。我想我现在比以前更困惑了,需要帮助正确设置它

public class AuthorizeCustomAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            var request = filterContext.RequestContext.HttpContext.Request;

            if (request.IsAjaxRequest())
            {
                var url = new UrlHelper(filterContext.RequestContext);
                var urlReferer = request.UrlReferrer != null
                    ? request.UrlReferrer.ToString()
                    : String.Empty;
                var signInUrl = url.Action("Index", "SignIn", new { Area = "Account", ReturnUrl = urlReferer });
                var accessDeniedUrl = url.Action("PageAccessDenied", "Error", new { Area = "" });
                if (!request.IsAuthenticated)
                {
                    //not authenticated
                    filterContext.Result =
                        CommonUtilities.AddJsonUtf8Encoding(new JsonResult
                        {
                            Data =
                                new {error = true, singinerror = true, message = "Sign in required!", url = signInUrl},
                            JsonRequestBehavior = JsonRequestBehavior.AllowGet
                        });
                }
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext.Request.IsAjaxRequest())
            {
                //Use [AuthorizeCustom(Roles="MyRole1,MyRole2")]
                //or [AuthorizeCustom]
                //roles may not have been applied here

                //checking authentication will be done by the HandleUnauthorizedRequest?????
                //if no roles are specified then it is true = so give access to the resource
                //user may have multiple roles or single role assigned, check and if not in role then return json back. 
                //....
            }
            else
            {
                return base.AuthorizeCore(httpContext);
            }
        }
    }

这帮助我设置了我的 http://www.dotnet-tricks.com/Tutorial/mvc/G54G220114-Custom-Authentication-and-Authorization-in-ASP.NET-MVC.html

使用

 [AuthorizeCustom(Roles = RoleNames.Admin)]

这是我的完整工作属性,没有任何清理。

public class AuthorizeCustomAttribute : AuthorizeAttribute
    {
        #region CONSTANTS

        public const string SectionStemFuture = "StemFuture";

        #endregion


        #region PROPERTIES

        private string Section { get; set; }

        #endregion

        #region Constructor

        public AuthorizeCustomAttribute()
        {
            Section = String.Empty;
        }

        public AuthorizeCustomAttribute(string section)
        {
            Section = section;
        }

        #endregion

        #region Overrides

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var request = filterContext.HttpContext.Request;

            var url = new UrlHelper(filterContext.RequestContext);

            /*
            var urlReferer = request.UrlReferrer != null
                ? request.UrlReferrer.ToString()
                : String.Empty;
            */
            var urlReferer = request.Url.PathAndQuery;

            var signInUrl = url.Action("Index", "SignIn", new { Area = "Account", ReturnUrl = urlReferer });
            var accessDeniedUrl = url.Action("PageAccessDenied", "Error", new { Area = "" });

            //overwrite the default sign in URL according to the section
            if (!String.IsNullOrWhiteSpace(Section))
            {
                switch (Section)
                {
                    case SectionStemFuture:
                        signInUrl = url.Action("Index", "StemFutureHome", new { Area = "StemFuture", ReturnUrl = urlReferer });
                        break;
                }
            }


            if (!request.IsAuthenticated)
            {
                //not authenticated
                if (request.IsAjaxRequest())
                {
                    filterContext.Result =
                        CommonUtilities.AddJsonUtf8Encoding(new JsonResult
                        {
                            Data =
                                new {error = true, signinerror = true, message = "Sign in required", url = signInUrl},
                            JsonRequestBehavior = JsonRequestBehavior.AllowGet
                        });
                }
                else
                {
                    //this is not an ajax request
                    if (!String.IsNullOrWhiteSpace(Section))
                    {
                        filterContext.Result = new RedirectResult(signInUrl);
                    }
                    else
                    {
                        //let the base authorization take care of it
                        base.OnAuthorization(filterContext);    
                    }
                }

            }
            else if (!String.IsNullOrWhiteSpace(base.Roles))
            {
                var isRoleError = true;
                var rolesAllowed = base.Roles.Split(',');
                //authenticated and we have some roles to check against
                var user = filterContext.HttpContext.User;
                if (user != null && rolesAllowed.Any())
                {
                    foreach (var role in rolesAllowed)
                    {
                        if (user.IsInRole(role))
                        {
                            isRoleError = false;
                        }
                    }
                }

                if (isRoleError)
                {
                    if (request.IsAjaxRequest())
                    {
                        filterContext.Result =
                            CommonUtilities.AddJsonUtf8Encoding(new JsonResult
                            {
                                Data =
                                    new
                                    {
                                        error = true,
                                        signinerror = true,
                                        message = "Access denied",
                                        url = accessDeniedUrl
                                    },
                                JsonRequestBehavior = JsonRequestBehavior.AllowGet
                            });
                    }
                    else
                    {
                        //here we will need to pass to the access denied
                        filterContext.Result = new RedirectResult(accessDeniedUrl);
                    }
                }

            }

        }

        #endregion
    }