您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“ASP.NET Core 3.0輕量級角色API控制授權(quán)庫的方法是什么”,內(nèi)容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“ASP.NET Core 3.0輕量級角色API控制授權(quán)庫的方法是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
ASP.NET Core 3.0 一個 jwt 的輕量角色/用戶、單個API控制的授權(quán)認證庫
ASP.NET Core 使用 JWT 自定義角色/策略授權(quán)需要實現(xiàn)的接口,利用微軟本身的授權(quán)認證,在此基礎(chǔ)上做拓展。特點是使用十分簡便,無需過多配置;因為本身沒有“造輪子”,所以如果需要改造,也十分簡單。
此庫更新到 .Net Core 3.0 了,如果需要在 2.2X 上使用,可以到倉庫下載項目,然后把 Nuget 包換成 2.2 的。
隨便新建一個網(wǎng)站或API項目,例如 MyAuth。
Nuget 里搜索 CZGL.Auth,按照 2.0.1 版本,或者使用 Package Manager 命令
Install-Package CZGL.Auth -Version 2.0.1
CZGL.Auth 設(shè)計思路是,網(wǎng)站可以存在多個角色、多個用戶、多個API,
一個角色擁有一些 API,可以添加或刪除角色或修改角色所有權(quán)訪問的 API;
一個用戶可以同時屬于幾個角色。
第一步要考慮網(wǎng)站的角色、用戶、API設(shè)計,
CZGL.Auth 把這些信息存儲到內(nèi)存中,一個用戶擁有那幾個角色、一個角色具有哪些API的訪問權(quán)限。
角色跟 API 是對應關(guān)系,用戶跟角色是多對多關(guān)系。
新建一個類 RoleService.cs ,引入 using CZGL.Auth.Services;
,RoleService 繼承 ManaRole。
通過以下接口操作角色權(quán)限信息
protected bool AddRole(RoleModel role); protected bool AddUser(UserModel user); protected bool RemoveRole(string roleName); protected bool RemoveUser(string userName);
很明顯,添加/移除一個角色,添加/移除一個用戶
假如有 A、B、C 三個角色,
有 /A、/B、/C、/AB、/AC、/BC、/ABC 共7個API,設(shè)定權(quán)限
A 可以訪問 A、AB、AC、ABC
B 可以訪問 B、AB、BC、ABC
C 可以訪問 C、AC、BC、ABC
這里采用模擬數(shù)據(jù)的方法,不從數(shù)據(jù)庫里面加載實際數(shù)據(jù)。
在 RoleService 里面增加一個方法
/// <summary> /// 用于加載角色和API /// </summary> public void UpdateRole() { List<RoleModel> roles = new List<RoleModel> { new RoleModel { RoleName="A", Apis=new List<OneApiModel> { new OneApiModel { ApiName="A", ApiUrl="/A" }, new OneApiModel { ApiName="AB", ApiUrl="/AB" }, new OneApiModel { ApiName="AC", ApiUrl="/AC" }, new OneApiModel { ApiName="ABC", ApiUrl="/ABC" } } }, new RoleModel { RoleName="B", Apis=new List<OneApiModel> { new OneApiModel { ApiName="B", ApiUrl="/B" }, new OneApiModel { ApiName="AB", ApiUrl="/AB" }, new OneApiModel { ApiName="BC", ApiUrl="/BC" }, new OneApiModel { ApiName="ABC", ApiUrl="/ABC" } } }, new RoleModel { RoleName="A", Apis=new List<OneApiModel> { new OneApiModel { ApiName="A", ApiUrl="/A" }, new OneApiModel { ApiName="AB", ApiUrl="/AB" }, new OneApiModel { ApiName="AC", ApiUrl="/AC" }, new OneApiModel { ApiName="ABC", ApiUrl="/ABC" } } } }; foreach (var item in roles) { AddRole(item); } }
有了角色和對應的API信息,就要添加用戶了,
假設(shè)有 aa、bb、cc 三個用戶,密碼都是 123456,aa 屬于 A 角色, bb 屬于 B角色...
public void UpdateUser() { AddUser(new UserModel { UserName = "aa", BeRoles = new List<string> { "A" } }); AddUser(new UserModel { UserName = "bb", BeRoles = new List<string> { "B" } }); AddUser(new UserModel { UserName = "cc", BeRoles = new List<string> { "C" } }); }
為了能夠把角色和用戶加載進 CZGL.Auth ,你需要在程序啟動時,例如在 Program 里,使用
RoleService roleService = new RoleService(); roleService.UpdateRole(); roleService.UpdateUser();
授權(quán)是,可能會有各種情況,你可以添加自定義事件記錄下用戶訪問的授權(quán)信息、影響授權(quán)結(jié)果。
引用 using CZGL.Auth.Interface;
,
添加一個類 RoleEvents 繼承 IRoleEventsHadner
public class RoleEvents : IRoleEventsHadner { public async Task Start(HttpContext httpContext) { await Task.CompletedTask; } public void TokenEbnormal(object eventsInfo) { } public void TokenIssued(object eventsInfo) { } public void NoPermissions(object eventsInfo) { } public void Success(object eventsInfo) { } public async Task End(HttpContext httpContext) { await Task.CompletedTask; } }
在 CZGL.Auth 開始驗證授權(quán)前調(diào)用 Start,結(jié)束時調(diào)用 End,傳入傳參數(shù)是 HttpContext 類型,你可以在里面添加自定義授權(quán)的信息,在里面可以影響請求管道。
其他幾個方法含義如下:
TokenEbnormal 客戶端攜帶的 Token 不是有效的 Jwt 令牌,將不能被解析
TokenIssued 令牌解碼后,issuer 或 audience不正確
NoPermissions 無權(quán)訪問此 API
在授權(quán)認證的各個階段將會調(diào)用上面的方法。
使用 CZGL.Auth ,你需要注入以下兩個服務
services.AddRoleService(authOptions); services.AddSingleton<IRoleEventsHadner, RoleEvents>();
AddRoleService
是注入授權(quán)服務,AddSingleton
注入你的事件。
AddRoleService 需要一個 AuthConfigModel 類型作參數(shù)。
你可以這樣配置
var authOptions = new AuthBuilder() .Security("aaaafsfsfdrhdhrejtrjrt", "ASPNETCORE", "ASPNETCORE") .Jump("accoun/login", "account/error", false, false) .Time(TimeSpan.FromMinutes(20)) .InfoScheme(new CZGL.Auth.Models.AuthenticateScheme { TokenEbnormal = "Login authentication failed!", TokenIssued = "Login authentication failed!", NoPermissions = "Login authentication failed!" }).Build(); services.AddRoleService(authOptions); services.AddSingleton<IRoleEventsHadner, RoleEvents>();
Security 配置密鑰相關(guān),參數(shù)分別是密鑰字符串、頒發(fā)者、訂閱者。
Jump 配置授權(quán)失敗時,跳轉(zhuǎn)地址。參數(shù)分別是未授權(quán)時跳轉(zhuǎn)、授權(quán)無效跳轉(zhuǎn),后面兩個 bool 可以設(shè)置跳轉(zhuǎn)或跳轉(zhuǎn)。
Time 配置 Token 有效期。
InfoScheme 授權(quán)失敗提示信息,例如
上圖的是時間過期的提示消息,用戶請求API失敗時返回 401 狀態(tài)碼,Header 會攜帶提示消息,CZGL.Auth 里面設(shè)置了三種情況下,自定義頭部:
TokenEbnormal 客戶端攜帶的 Token 不是有效的 Jwt 令牌,將不能被解析
TokenIssued 令牌解碼后,issuer 或 audience不正確
NoPermissions 無權(quán)訪問此 API
添加三個中間件
app.UseAuthentication(); app.UseAuthorization(); app.UseMiddleware<RoleMiddleware>();
app.UseAuthorization();
是微軟授權(quán)認證的中間件,CZGL.Auth 會先讓,默認的驗證管道過濾一些無效請求和認證信息,再由 CZGL.Auth 來校驗授權(quán)。
很簡單,CZGL.Auth 的認證授權(quán),你只需在 Controller 或 Action上 添加 [Authorize]
。
CZGL.Auth 只會對使用了 [Authorize]
特性的 Controller 或 Action 生效。
如果一個 Controller 已經(jīng)設(shè)置了 [Authorize]
,但是你想里面的 Action 跳過授權(quán)認證,則使用 [AllowAnonymous]
修飾 Action。
使用方法跟微軟的默認的完全一致。這樣無需過多配置。
如果你想另外定義一個特性用來另外設(shè)置 授權(quán)的話,可以到我的倉庫提 Issue 或者直接聯(lián)系我微信。
添加一個 APIController ,
[Authorize] [Route("api/[controller]")] [ApiController] public class TestController : ControllerBase { [HttpGet("/A")] public JsonResult A() { return new JsonResult(new { Code = 200, Message = "Success!" }); } [HttpGet("/B")] public JsonResult B() { return new JsonResult(new { Code = 200, Message = "Success!" }); } [HttpGet("/C")] public JsonResult C() { return new JsonResult(new { Code = 200, Message = "Success!" }); } [HttpGet("/AB")] public JsonResult AB() { return new JsonResult(new { Code = 200, Message = "Success!" }); } [HttpGet("/BC")] public JsonResult BC() { return new JsonResult(new { Code = 200, Message = "Success!" }); } [HttpGet("/AC")] public JsonResult AC() { return new JsonResult(new { Code = 200, Message = "Success!" }); } [HttpGet("/ABC")] public JsonResult ABC() { return new JsonResult(new { claims = User.Claims }); } /// <summary> /// 任何人都不能訪問 /// </summary> /// <returns></returns> [HttpGet("D")] public JsonResult D() { return new JsonResult(new { Code = 200, Message = "Success!" }); } [HttpGet("error")] public JsonResult Denied() { return new JsonResult( new { Code = 0, Message = "訪問失敗!", Data = "此賬號無權(quán)訪問!" }); } }
添加一個 AccountController.cs 用來頒發(fā)登錄、 Token。
[Route("api/[controller]")] [ApiController] public class AccountController : ControllerBase { [HttpPost("/Login")] public async Task<JsonResult> Login([FromQuery]string username, string password, string rolename) { // 用戶名密碼是否正確 if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(rolename)) { return new JsonResult(new { Code = 0, Message = "尼瑪,上傳什么垃圾信息", }); } if(!((username=="aa"||username=="bb"||username=="cc")&&password=="123456")) { return new JsonResult(new { Code = 0, Message = "賬號或密碼錯誤", }); } // 你自己定義的角色/用戶信息服務 RoleService roleService = new RoleService(); // 檢驗用戶是否屬于此角色 var role = roleService.IsUserToRole(username,rolename); // CZGL.Auth 中一個用于加密解密的類 EncryptionHash hash = new EncryptionHash(); // 設(shè)置用戶標識 var userClaims = hash.BuildClaims(username, rolename); //// 自定義構(gòu)建配置用戶標識 /// 自定義的話,至少包含如下標識 //var userClaims = new Claim[] //{ //new Claim(ClaimTypes.Name, userName), // new Claim(ClaimTypes.Role, roleName), // new Claim(JwtRegisteredClaimNames.Aud, Audience), // new Claim(ClaimTypes.Expiration, TimeSpan.TotalSeconds.ToString()), // new Claim(JwtRegisteredClaimNames.Iat, new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()) //}; /* iss (issuer):簽發(fā)人 exp (expiration time):過期時間 sub (subject):主題 aud (audience):受眾 nbf (Not Before):生效時間 iat (Issued At):簽發(fā)時間 jti (JWT ID):編號 */ // 方法一,直接頒發(fā) Token ResponseToken token = hash.BuildToken(userClaims); //方法二,拆分多步,頒發(fā) token,方便調(diào)試 //var identity = hash.GetIdentity(userClaims); //var jwt = hash.BuildJwtToken(userClaims); //var token = hash.BuildJwtResponseToken(jwt); return new JsonResult(token); } }
注入 Jwt 服務、頒發(fā) Token
CZGL.Auth 把使用 jwt 的服務和頒發(fā) Token 的代碼封裝好了,這個庫不是在“造輪子”,所以實際上你可以很輕松的把這部分的代碼抽出來,另外設(shè)計。
這部分的代碼所在位置 RoleServiceExtension.cs 、EncryptionHash.cs。
授權(quán)中間件
app.UseAuthentication(); app.UseAuthorization(); app.UseMiddleware<RoleMiddleware>();
我的寫法是利用 ASP.NET Core 的 jwt 完成基礎(chǔ)的認證授權(quán),然后在下一個管道中實現(xiàn)拓展的認證。但是本身的認證是在 app.UseAuthorization(); 做了拓展,所以使用 CZGL.Auth,只需要按照平常 jwt 的方式去使用,只是加了一個 RoleMiddleware 中間件。
CZGL.Auth 只是我受到新思路啟發(fā)臨時寫出來的。。。最好不要直接用于生產(chǎn),去 github 庫把項目下載下來,按照自己應用場景改一下~。
先使用 aa 用戶登錄,登錄時選擇 A 角色。
因為 A 用戶只能訪問 “帶有 A ” 的API, "/A"、"/AB" 等,所以我們可以試試。
繼續(xù)用這個 Token 訪問一下 "/B"
可以繼續(xù)嘗試添加 API 或者使用其他用戶登錄,訪問不同的 API。
由于別人對前端不熟,所以就不寫帶頁面的示例了~。
可以用 Postman 就行測試。
什么示例的 項目可以到倉庫里下載,名稱是 MyAuth。
一般上,用戶權(quán)限、角色權(quán)限信息是存儲在數(shù)據(jù)庫里面的,另一個示例是 CZGL.Auth.Sample2。
讀到這里,這篇“ASP.NET Core 3.0輕量級角色API控制授權(quán)庫的方法是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。