Как перенести логику реализации политики настраиваемых атрибутов авторизации в автозагрузку?

Я реализовал настраиваемый атрибут [Authorize] в приложении ASP.NET MVC Core 3.1. Основная причина, по которой у меня есть собственный, заключается в том, что приложение использует много AJAX, и я не мог понять, как заставить его работать с AJAX. Атрибут также реализует 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
}

person Lukas    schedule 30.03.2021    source источник
comment
Вы имеете в виду, что хотите поместить логику для политик в Startup.cs, а затем передать политику в пользовательский атрибут ActionFilterAttribute AuthorizeUser?   -  person Yiyi You    schedule 01.04.2021
comment
Да, я это имел в виду. Таким образом, логика политики находится в Startup.cs, а не в атрибуте AuthorizeUser.   -  person Lukas    schedule 01.04.2021