如何将自定义授权属性策略实现逻辑移到启动?

时间:2021-03-30 17:10:18

标签: c# asp.net asp.net-core action-filter authorize-attribute

我在 ASP.NET MVC Core 3.1 应用程序中实现了自定义 [Authorize] 属性。我有一个自定义的主要原因是因为该应用程序使用了很多 AJAX,而我不知道如何让它与 AJAX 一起工作。由于我发布的关于 here 的问题,该属性还实现了 ActionFilterAttribute 而不是 IAuthorizationFilter。拥有这个自定义属性意味着实现我自己的逻辑来处理角色,我做到了。

我还实现了代码来处理对角色进行分组的策略,但代码位于属性本身内部。当开发人员考虑更改 MVC 框架内的政策时,他们可能会想到Startup.cs

如何将策略逻辑放在 Startup.cs 中并让我的自定义属性使用它?

自定义属性:

public class AuthorizeUser : ActionFilterAttribute
{
    public Policies Policy { get; set; }

    public AuthorizeUser(Policies policy)
    {
        Policy = policy;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        string signInPageUrl = "/UserAccess/Index";
        string notAuthorizedUrl = "/UserAccess/NotAuthorized";

        if (context.HttpContext.User.Identity.IsAuthenticated)
        {
            List<string> roles = GetRolesByPolicy(Policy);
            bool userHasRole = false;
            foreach (var role in roles)
            {
                if (context.HttpContext.User.IsInRole(role.ToUpper()))
                {
                    userHasRole = true;
                }
            }

            if (userHasRole == false)
            {
                if (context.HttpContext.Request.IsAjaxRequest())
                {
                    context.HttpContext.Response.StatusCode = 401;
                    JsonResult jsonResult = new JsonResult(new { redirectUrl = notAuthorizedUrl });
                    context.Result = jsonResult;
                }

                else
                {
                    context.Result = new RedirectResult(notAuthorizedUrl);
                }
            }
        }
        else
        {
            if (context.HttpContext.Request.IsAjaxRequest())
            {
                context.HttpContext.Response.StatusCode = 403;
                JsonResult jsonResult = new JsonResult(new { redirectUrl = signInPageUrl });
                context.Result = jsonResult;
            }
            else
            {
                context.Result = new RedirectResult(signInPageUrl);
            }
        }
    }

    private List<string> GetRolesByPolicy(Policies policy)
    {
        List<RoleModel.Roles> roleEnums = new List<RoleModel.Roles>();
        roleEnums.Add(RoleModel.Roles.Admin); //admin is always allowed all actions
        switch (policy)
        {
            case Policies.EditUsers:
                roleEnums.AddRange(new List<RoleModel.Roles>
                {
                    RoleModel.Roles.User,
                    RoleModel.Roles.Customer,
                    RoleModel.Roles.Developer,
                    RoleModel.Roles.Manager
                });
                break;

            case Policies.ManageOrders:
                roleEnums.AddRange(new List<RoleModel.Roles>
                {
                    RoleModel.Roles.User,
                    RoleModel.Roles.Customer
                });
                break;

            case Policies.SendOrders:
                roleEnums.AddRange(new List<RoleModel.Roles>
                {
                    RoleModel.Roles.User
                });
                break;
        }

        return roleEnums.ConvertAll(r => r.ToString());
    }
}

政策枚举

public enum Policies
{
    EditUsers,
    ManageOrders,
    SendOrders
}

0 个答案:

没有答案