Authorization其目標就是驗證Http請求能否通過驗證。ASP.Net Core提供了很多種Authorization方式,詳細可以參考 微軟官方文檔。在這里只詳細介紹2種方式:
- Policy
- Custom Attribute
1. Policy : 策略授權
先定義一個IAuthorizationRequirement類來定義策略的要求,以下例子支持傳遞一個age參數。
public class AdultPolicyRequirement : IAuthorizationRequirement { public int Age { get; } public AdultPolicyRequirement(int age) { //年齡限制 this.Age = age; } }
然后定義策略要求的Handler,當提供的Controller被請求時先根據請求的Http報文來決定是否可以通過驗證。
public class AdultAuthorizationHandler : AuthorizationHandler { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AdultPolicyRequirement requirement) { //獲取當前http請求的context對象 var mvcContext = context.Resource as AuthorizationFilterContext; //以下代碼都不是必須的,只是展示一些使用方法,你可以選擇使用 ...... // var age = mvcContext.HttpContext.Request.Query.FirstOrDefault(u => u.Key == "age"); if (age.Value.Count <= 0|| Convert.ToInt16(age.Value[0]) < requirement.Age) { context.Fail(); } else { //通過驗證,這句代碼必須要有 context.Succeed(requirement); } return Task.CompletedTask; } }
還需要在啟動時,在services里注冊定義的策略和對應的Handler
//添加二種認證策略,一種以12歲為界限,一種是18歲 services.AddAuthorization(options => { options.AddPolicy("Adult1", policy => policy.Requirements.Add(new AdultPolicyRequirement(12))); options.AddPolicy("Adult2", policy => policy.Requirements.Add(new AdultPolicyRequirement(18))); }); //添加策略驗證handler services.AddSingleton();
最后在相應的Controller前加上Authroize特性 [Authorize("Adult1")]
。總體上Policy這種方式比較簡單,但是也有不靈活的地方,不同的策略要求都需要提前在services里注冊。完整的例子可以參考 PolicySample
2. Custom Attribute:自定義特性
這里其實是第一種Policy策略和自定義特性的結合,從而實現在Controller的具體方法位置自定義不同參數的Policy策略。
首先需要定義這個Attribute和策略要求類
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] public class PermissionCheckAttribute : AuthorizeAttribute { public string Id { get; set; } public int Operation { get; set; } public PermissionCheckAttribute() : base("PermissionCheck") { } } public class PermissionCheckPolicyRequirement : IAuthorizationRequirement { //Add any custom requirement properties if you have them public PermissionCheckPolicyRequirement() { } }
再定義策略和Attribute對應的Handler處理類
public class PermissionCheckPolicyHandler : AttributeAuthorizationHandler<PermissionCheckPolicyRequirement, PermissionCheckAttribute> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext authoriazationContext, PermissionCheckPolicyRequirement requirement, IEnumerable<PermissionCheckAttribute> attributes) { var context = authoriazationContext.Resource as AuthorizationFilterContext; foreach (var permissionAttribute in attributes) { this.checkPermission(context, permissionAttribute.Id, permissionAttribute.Operation); } authoriazationContext.Succeed(requirement); return Task.FromResult<object>(null); } private void checkPermission(AuthorizationFilterContext context, string _Id, int _Operation) { if (_Operation > 0) { if (_Id != "user1") { throw new Exception("不具備操作權限"); } } else { //dosomething } return; } }
同樣還需要在service里添加策略和策略處理類,這里不貼代碼了。最后在Controller里使用帶參數的Attribute,類似如下:
[HttpGet] [PermissionCheck (Id ="user1", Operation=2)] public IEnumerable Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 [HttpGet("{id}")] [PermissionCheck(Id = "user2", Operation = 4)] public string Get(int id) { return "value"; }
完整的代碼參考Github地址
轉:https://www.jianshu.com/p/0ed4d820809c