IdentityServer4 QuckStart 授權(quán)與自定義Claims的問題
最近在折騰IdentityServer4,為了簡單,直接使用了官方給的QuickStart示例項目作為基礎(chǔ)進行搭建。有一說一,為了保護一個API,感覺花費的時間比寫一個API還要多。
本文基于ASP.NET CORE 3.1, IdentityServer4 3.1.3。代碼皆為關(guān)鍵代碼,貼全了太多了。
好不容易跑起來了,最終的任務(wù)要落實到授權(quán)的工作上來。在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())); }
然而在使用的時候,雖然正確取得授權(quán),但是卻無法正常訪問API,一直提示401沒有授權(quán)錯誤。仔細檢查,發(fā)現(xiàn)IdentityServer4返回的內(nèi)容并沒有返回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" ] }
實現(xiàn)
查看Config.cs,IdentityServer4默認只返回兩種IdentityResource:openid和profile。按照官方的說法,這個東西定義的內(nèi)容會返回到用戶的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" } },
執(zhí)行之前,需要確保數(shù)據(jù)庫中的用戶數(shù)據(jù),已經(jīng)包含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"),
運行程序,返回值依舊沒有任何變化,很挫敗,只能繼續(xù)折騰。
有研究通過實現(xiàn)IProfileService
達到自定義Cliams。文章寫的很詳細,我這就不重復(fù)了,我實際試驗過,可以成功。
但是文章末尾的注意,很重要。
“那么, 通過profileservice頒發(fā)的claims, 任意clients都能拿到”
說明這個優(yōu)先級是非常高的,可以覆蓋所有的行為,當然我們可以在IProfileService
的實現(xiàn)上對權(quán)限進行進一步的設(shè)置,不過還是挺麻煩的。參考實現(xiàn),參考官方
作為懶人,必然不想再費勁去折騰權(quán)限的問題,那么是否有簡單點的辦法呢?
網(wǎng)上有一些問答說到了可以通過設(shè)置Scopes來達到目的。不過過于久遠,IdentityServer4已經(jīng)沒有這個獨立的類了,說是已經(jīng)被ApiResource
取代了。
直覺上這個東西應(yīng)該是指示要保護的API的相關(guān)內(nèi)容的,好像和這個沒啥關(guān)系,不過也只能死馬當活馬醫(yī)了。修改config.cs,最終如下內(nèi)容:
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" } },
返回結(jié)果如下:
{ "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并且設(shè)置AlwaysSendClientClaims
和AlwaysIncludeUserClaimsInIdToken
之后,會在token中添加client_roie
字段,這個是沒辦法用與授權(quán)的,可以理解為IdentityServer4直接指定了Client角色,并不是Identity中的角色概念。
后記
回過頭來仔細看官方的文檔,ApiResource中的UserClaims就是用來干這個的,折騰了半天,不如當時仔細看看文檔了。
到此這篇關(guān)于IdentityServer4 QuckStart 授權(quán)與自定義Claims的文章就介紹到這了,更多相關(guān)IdentityServer4 QuckStart Claims內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
增加asp.net應(yīng)用程序性能的20種方法(簡單有效)
增加asp.net應(yīng)用程序性能的20種方法小結(jié),需要的朋友可以參考下,對于服務(wù)器也需要一些設(shè)置。2010-01-01asp.net core webapi 服務(wù)端配置跨域的實例
下面小編就為大家分享一篇asp.net core webapi 服務(wù)端配置跨域的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12google suggest 下拉菜單實現(xiàn)代碼(asp.net版本)
原來發(fā)表過,是asp版本的,但是不支持上下鍵,現(xiàn)在后臺處理程序用.net寫的。代碼進行部分優(yōu)化。2009-07-07用javascript為DropDownList控件下拉式選擇添加一個Item至定義索引位置
用Javascript為DropDownList控件下拉式選擇添加一個Item至定義索引位置;準備數(shù)據(jù),創(chuàng)建一個對象,將是存儲DropDownList控件每個Item數(shù)據(jù)2013-01-01asp.net使用JS+form表單Post和Get方式提交數(shù)據(jù)
今天小編就為大家分享一篇關(guān)于asp.net使用JS+form表單Post和Get方式提交數(shù)據(jù),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-01-01