在早期版本的ASP.NET Core中,可以通过重写bool AuthorizeCore(HttpContextBase httpContext)
来创建自定义AuthorizeAttribute
。然而,此方法在AuthorizeAttribute
中已不再存在。
当前创建自定义AuthorizeAttribute
的方法是使用新的策略设计,其文档此处。这种新方法的基本思想是使用新的[Authorize]
特性来指定一个“策略”(例如[Authorize(Policy = "YouNeedToBe18ToDoThis")]
),该策略在应用程序的Startup.cs
中注册,以执行某些代码块(即确保用户拥有一个年龄声明,其中年龄为18岁或以上)。
策略设计是对框架的一个很好的补充,ASP.Net安全核心团队应该为此表示赞扬。也就是说,它并不适用于所有情况。这种方法的缺点是它未能为最常见的需求提供便捷的解决方案:简单地断言给定的控制器或操作需要给定的声明类型。如果应用程序可能有数百个离散的权限来管理单个REST资源上的CRUD操作(“CanCreateOrder”、“CanReadOrder”、“CanUpdateOrder”、“CanDeleteOrder”等),则新方法要么需要在策略名称和声明名称之间进行重复的一对一映射(例如options.AddPolicy("CanUpdateOrder", policy => policy.RequireClaim(MyClaimTypes.Permission, "CanUpdateOrder"));
),要么编写一些代码在运行时执行这些注册(例如,从数据库读取所有声明类型并在循环中执行上述调用)。对于大多数情况而言,这种方法的问题在于它是多余的开销。
虽然ASP.Net Core安全团队建议不要创建您自己的解决方案,但在某些情况下,这可能是最谨慎的起始选项。
以下是使用IAuthorizationFilter
的实现,它提供了一种简单的方法来表达给定控制器或操作的声明需求:
<code class="language-csharp">public class ClaimRequirementAttribute : TypeFilterAttribute { public ClaimRequirementAttribute(string claimType, string claimValue) : base(typeof(ClaimRequirementFilter)) { Arguments = new object[] { new Claim(claimType, claimValue) }; } } public class ClaimRequirementFilter : IAuthorizationFilter { readonly Claim _claim; public ClaimRequirementFilter(Claim claim) { _claim = claim; } public void OnAuthorization(AuthorizationFilterContext context) { var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == _claim.Type && c.Value == _claim.Value); if (!hasClaim) { context.Result = new ForbidResult(); } } } [Route("api/resource")] public class MyController : Controller { [ClaimRequirement(MyClaimTypes.Permission, "CanReadResource")] [HttpGet] public IActionResult GetResource() { return Ok(); } }</code>
以上是如何在ASP.NET Core中创建自定义授权材料以满足简单索赔要求?的详细内容。更多信息请关注PHP中文网其他相关文章!