【发布时间】:2016-07-26 12:58:06
【问题描述】:
我正在尝试使用 aspnet 核心实现基于权限的访问控制。为了动态管理用户角色和权限(create_product、delete_product 等),它们存储在数据库中。数据模型就像http://i.stack.imgur.com/CHMPE.png
在 aspnet 核心(在 MVC 5 中)之前,我使用自定义 AuthorizeAttribute 来处理问题,如下所示:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
private readonly string _permissionName { get; set; }
[Inject]
public IAccessControlService _accessControlService { get; set; }
public CustomAuthorizeAttribute(string permissionName = "")
{
_permissionName = permissionName;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
var user = _accessControlService.GetUser();
if (PermissionName != "" && !user.HasPermission(_permissionName))
{
// set error result
filterContext.HttpContext.Response.StatusCode = 403;
return;
}
filterContext.HttpContext.Items["CUSTOM_USER"] = user;
}
}
然后我在下面的操作方法中使用它:
[HttpGet]
[CustomAuthorize(PermissionEnum.PERSON_LIST)]
public ActionResult Index(PersonListQuery query){ }
此外,我在视图中使用 HttpContext.Items["CUSTOM_USER"] 来显示或隐藏 html 部分:
@if (CurrentUser.HasPermission("<Permission Name>"))
{
}
当我决定切换 aspnet 核心时,我的所有计划都失败了。因为AuthorizeAttribute 中没有虚拟的OnAuthorization 方法。我尝试了一些方法来解决问题。如下:
使用新的基于策略的授权(我认为它不适合 我的场景)
使用自定义
AuthorizeAttribute和AuthorizationFilter(我读过这个 发布https://stackoverflow.com/a/35863514/5426333,但我无法正确更改)使用自定义中间件(如何获取当前的
AuthorizeAttribute行动?)使用 ActionFilter(出于安全目的是否正确?)
我无法决定哪种方式最适合我的场景以及如何实施。
第一个问题:MVC5 实施是不好的做法吗?
第二个问题:你对实现aspnet core有什么建议吗?
【问题讨论】:
-
为什么您认为基于策略的授权不适合您的情况?您仍然可以创建
PermissionRequirement实现IAuthorizationRequirement和一个处理程序,然后将其添加为options.AddPolicy("PersonList", policy => policy.Requirements.Add(new PermissionRequirement("PersonList"))); -
因为,我想从数据库中获取用户权限。
-
不,这是 1 个需求和 1 个处理程序(尽管一个需求可以由多个处理程序处理)。您只需要 500 个策略注册,您可以在循环中添加它们
-
我对答案添加了一个小更新。如果
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();使用DbContext,则services.AddSingleton<IAuthorizationHandler, PermissionHandler>();应该是services.AddScope<IAuthorizationHandler, PermissionHandler>();,因为DbContext是并且应该根据请求进行解析,而不是在应用程序的生命周期内解析 -
“您只需要 500 个策略注册”。这对我来说似乎很麻烦(想象一下预先存在的 .NET MVC 完整框架应用程序,它是具有多个后端数据库的多租户环境,只有在该租户的第一个请求进入时才能访问)。可以将事情更改为使用基于策略的方法,但对于旧世界中使用自定义授权属性非常简单的事情来说,这似乎非常迂回。
标签: c# asp.net-mvc asp.net-core access-control