Я реализовал настраиваемый атрибут [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
}
Startup.cs
, а не в атрибутеAuthorizeUser
. - person Lukas   schedule 01.04.2021