您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么將Claims授權與自定義IdentityServer4 QuckStart”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么將Claims授權與自定義IdentityServer4 QuckStart”吧!
最近在折騰IdentityServer4,為了簡單,直接使用了官方給的QuickStart示例項目作為基礎進行搭建。有一說一,為了保護一個API,感覺花費的時間比寫一個API還要多。
本文基于ASP.NET CORE 3.1, IdentityServer4 3.1.3。代碼皆為關鍵代碼,貼全了太多了。
好不容易跑起來了,最終的任務要落實到授權的工作上來。在API中使用Authorize
用來限制用戶的訪問。
[Route("api/[controller]")] [Authorize(Roles = "Administrator")] [ApiController] public class UserInfoController : ControllerBase { /// <summary> /// 無參GET請求 /// </summary> /// <returns></returns> [HttpGet()] [ProducesResponseType(typeof(ReturnData<IEnumerable<UserInfo>>), Status200OK)] public async Task<ActionResult> Get() { var info = new Info<UserInfo>(); return Ok(new ReturnData<IEnumerable<UserInfo>>(await info.Get())); }
然而在使用的時候,雖然正確取得授權,但是卻無法正常訪問API,一直提示401沒有授權錯誤。仔細檢查,發現IdentityServer4返回的內容并沒有返回role的JwtClaimTypes
,沒有它,Authorize
無法正常工作。
{ "nbf": 1587301921, "exp": 1587305521, "iss": "http://localhost:5000", "aud": "MonitoringSystemApi", "client_id": "webClient", "sub": "c6c18d4d-c28e-4de5-86dd-779121216204", "auth_time": 1587301921, "idp": "local", "scope": [ "roles", "MonitoringSystemApi", "offline_access" ], "amr": [ "pwd" ] }
實現
查看Config.cs,IdentityServer4默認只返回兩種IdentityResource:openid和profile。按照官方的說法,這個東西定義的內容會返回到用戶的token。參考。那么就果斷給它安排。
public static IEnumerable<IdentityResource> Ids => new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResource ("roles", new List<string> { JwtClaimTypes.Role }){ Required = true} }; public static IEnumerable<Client> Clients => new List<Client> { new Client { ClientId = "webClient", ClientSecrets = { new Secret("secret".Sha256()) }, AllowOfflineAccess = true, AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, // scopes that client has access to AllowedScopes = { "roles", "MonitoringSystemApi" } },
執行之前,需要確保數據庫中的用戶數據,已經包含role的Claim。
//添加用戶代碼 bob = new ApplicationUser { UserName = "bob" }; var result = userMgr.CreateAsync(bob, "Pass123$").Result; if (!result.Succeeded) { throw new Exception(result.Errors.First().Description); } result = userMgr.AddClaimsAsync(bob, new Claim[]{ new Claim(JwtClaimTypes.Role, "Administrator"), new Claim(JwtClaimTypes.Name, "Bob Smith"),
運行程序,返回值依舊沒有任何變化,很挫敗,只能繼續折騰。
有研究通過實現IProfileService
達到自定義Cliams。文章寫的很詳細,我這就不重復了,我實際試驗過,可以成功。
但是文章末尾的注意,很重要。
“那么, 通過profileservice頒發的claims, 任意clients都能拿到”
說明這個優先級是非常高的,可以覆蓋所有的行為,當然我們可以在IProfileService
的實現上對權限進行進一步的設置,不過還是挺麻煩的。參考實現,參考官方
作為懶人,必然不想再費勁去折騰權限的問題,那么是否有簡單點的辦法呢?
網上有一些問答說到了可以通過設置Scopes來達到目的。不過過于久遠,IdentityServer4已經沒有這個獨立的類了,說是已經被ApiResource
取代了。
直覺上這個東西應該是指示要保護的API的相關內容的,好像和這個沒啥關系,不過也只能死馬當活馬醫了。修改config.cs,最終如下內容:
public static IEnumerable<ApiResource> Apis => new List<ApiResource> { new ApiResource("pls", new[]{ "role"}), }; public static IEnumerable<Client> Clients => new List<Client> { new Client { ClientId = "webClient", ClientSecrets = { new Secret("secret".Sha256()) }, AllowOfflineAccess = true, AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, // scopes that client has access to AllowedScopes = { "pls" } },
返回結果如下:
{ "nbf": 1587301799, "exp": 1587305399, "iss": "http://localhost:5000", "aud": "pls", "client_id": "webClient", "sub": "c6c18d4d-c28e-4de5-86dd-779121216204", "auth_time": 1587301799, "idp": "local", "role": "Administrator", "scope": [ "pls", "offline_access" ], "amr": [ "pwd" ] }
終于看見心心念念的自定義Claim(role),可以去訪問API了。
注意,在Client中也有個Claims,添加了role并且設置AlwaysSendClientClaims
和AlwaysIncludeUserClaimsInIdToken
之后,會在token中添加client_roie
字段,這個是沒辦法用與授權的,可以理解為IdentityServer4直接指定了Client角色,并不是Identity中的角色概念。
后記
回過頭來仔細看官方的文檔,ApiResource中的UserClaims就是用來干這個的,折騰了半天,不如當時仔細看看文檔了。
感謝各位的閱讀,以上就是“怎么將Claims授權與自定義IdentityServer4 QuckStart”的內容了,經過本文的學習后,相信大家對怎么將Claims授權與自定義IdentityServer4 QuckStart這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。