我在 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
}