【发布时间】:2017-03-15 18:08:31
【问题描述】:
在我的多租户应用程序中,每个租户都设置了用户权限(如果您更愿意,请阅读角色),因此我们向每个用户添加声明,其值为 TenantName:权限.
我们正在使用基于策略的授权和使用以下代码的自定义代码
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class PermissionAuthorizeAttribute : AuthorizeAttribute
{
public Permission[] AcceptedPermissions { get; set; }
public PermissionAuthorizeAttribute()
{
}
public PermissionAuthorizeAttribute(params Permission[] acceptedPermissions)
{
AcceptedPermissions = acceptedPermissions;
Policy = "RequirePermission";
}
}
public enum Permission
{
Login = 1,
AddUser = 2,
EditOtherUser = 3,
EditBaseData = 6,
EditSettings = 7,
}
用上面的代码我们装饰控制器动作
[PermissionAuthorize(Permission.EditSettings)]
public IActionResult Index()
在 startup.cs 我们有
services.AddAuthorization(options =>
{
options.AddPolicy("RequirePermission", policy => policy.Requirements.Add(new PermissionRequirement()));
});
在这种情况下,AuthorizationHandler 需要访问 PermissionAuthorizeAttribute,以便我们可以检查在操作上指定了哪些权限。目前我们可以通过以下代码获取属性,但我认为必须有更简单的方法,因为那里有很多强制转换。
public class PermissionRequirement : AuthorizationHandler<PermissionRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
var filters = ((FilterContext)context.Resource).Filters;
PermissionAuthorizeAttribute permissionRequirement = null;
foreach (var filter in filters)
{
var authorizeFilter = filter as AuthorizeFilter;
if (authorizeFilter == null || authorizeFilter.AuthorizeData == null)
continue;
foreach (var item in authorizeFilter.AuthorizeData)
{
permissionRequirement = item as PermissionAuthorizeAttribute;
if (permissionRequirement != null)
break;
}
if (permissionRequirement != null)
break;
}
//TODO Check that the user has the required claims
context.Succeed(requirement);
return Task.CompletedTask;
}
}
我找到的所有示例都是这样的,其中在 startup.cs 中指定了一些硬连线策略。 services.AddAuthorization(选项 => { options.AddPolicy("Over21", 政策 => policy.Requirements.Add(new MinimumAgeRequirement(21))); }
在这里你用
装饰你的控制器或动作[Authorize(Policy="Over21")]
public class AlcoholPurchaseRequirementsController : Controller
我认为如果您可以像这样在控制器/动作中指定年龄,上面的示例会更好
[Authorize(Policy="OverAge", Age=21)]
public class AlcoholPurchaseRequirementsController : Controller
现在您需要为每个最低年龄添加不同的策略。
关于如何提高效率的任何想法?
【问题讨论】:
-
您是否考虑过使用基于资源的授权(docs.asp.net/en/latest/security/authorization/…)?如果您采用这种方法,您可以将年龄作为资源发送。但是在这种情况下,您不能使用
Authorize属性。
标签: security asp.net-core