IdentityServer4 QuckStart 授權(quán)與自定義Claims的問(wèn)題
最近在折騰IdentityServer4,為了簡(jiǎn)單,直接使用了官方給的QuickStart示例項(xiàng)目作為基礎(chǔ)進(jìn)行搭建。有一說(shuō)一,為了保護(hù)一個(gè)API,感覺(jué)花費(fèi)的時(shí)間比寫一個(gè)API還要多。
本文基于ASP.NET CORE 3.1, IdentityServer4 3.1.3。代碼皆為關(guān)鍵代碼,貼全了太多了。
好不容易跑起來(lái)了,最終的任務(wù)要落實(shí)到授權(quán)的工作上來(lái)。在API中使用Authorize用來(lái)限制用戶的訪問(wèn)。
[Route("api/[controller]")]
[Authorize(Roles = "Administrator")]
[ApiController]
public class UserInfoController : ControllerBase
{
/// <summary>
/// 無(wú)參GET請(qǐng)求
/// </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()));
}
然而在使用的時(shí)候,雖然正確取得授權(quán),但是卻無(wú)法正常訪問(wèn)API,一直提示401沒(méi)有授權(quán)錯(cuò)誤。仔細(xì)檢查,發(fā)現(xiàn)IdentityServer4返回的內(nèi)容并沒(méi)有返回role的JwtClaimTypes,沒(méi)有它,Authorize無(wú)法正常工作。
{
"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"
]
}
實(shí)現(xiàn)
查看Config.cs,IdentityServer4默認(rèn)只返回兩種IdentityResource:openid和profile。按照官方的說(shuō)法,這個(gè)東西定義的內(nèi)容會(huì)返回到用戶的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ù)庫(kù)中的用戶數(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"),
運(yùn)行程序,返回值依舊沒(méi)有任何變化,很挫敗,只能繼續(xù)折騰。
有研究通過(guò)實(shí)現(xiàn)IProfileService達(dá)到自定義Cliams。文章寫的很詳細(xì),我這就不重復(fù)了,我實(shí)際試驗(yàn)過(guò),可以成功。
但是文章末尾的注意,很重要。
“那么, 通過(guò)profileservice頒發(fā)的claims, 任意clients都能拿到”
說(shuō)明這個(gè)優(yōu)先級(jí)是非常高的,可以覆蓋所有的行為,當(dāng)然我們可以在IProfileService的實(shí)現(xiàn)上對(duì)權(quán)限進(jìn)行進(jìn)一步的設(shè)置,不過(guò)還是挺麻煩的。參考實(shí)現(xiàn),參考官方
作為懶人,必然不想再費(fèi)勁去折騰權(quán)限的問(wèn)題,那么是否有簡(jiǎn)單點(diǎn)的辦法呢?
網(wǎng)上有一些問(wèn)答說(shuō)到了可以通過(guò)設(shè)置Scopes來(lái)達(dá)到目的。不過(guò)過(guò)于久遠(yuǎn),IdentityServer4已經(jīng)沒(méi)有這個(gè)獨(dú)立的類了,說(shuō)是已經(jīng)被ApiResource取代了。
直覺(jué)上這個(gè)東西應(yīng)該是指示要保護(hù)的API的相關(guān)內(nèi)容的,好像和這個(gè)沒(méi)啥關(guān)系,不過(guò)也只能死馬當(dāng)活馬醫(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"
]
}
終于看見(jiàn)心心念念的自定義Claim(role),可以去訪問(wèn)API了。
注意,在Client中也有個(gè)Claims,添加了role并且設(shè)置AlwaysSendClientClaims和AlwaysIncludeUserClaimsInIdToken之后,會(huì)在token中添加client_roie字段,這個(gè)是沒(méi)辦法用與授權(quán)的,可以理解為IdentityServer4直接指定了Client角色,并不是Identity中的角色概念。
后記
回過(guò)頭來(lái)仔細(xì)看官方的文檔,ApiResource中的UserClaims就是用來(lái)干這個(gè)的,折騰了半天,不如當(dāng)時(shí)仔細(xì)看看文檔了。
到此這篇關(guān)于IdentityServer4 QuckStart 授權(quán)與自定義Claims的文章就介紹到這了,更多相關(guān)IdentityServer4 QuckStart Claims內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- IdentityServer4實(shí)現(xiàn).Net Core API接口權(quán)限認(rèn)證(快速入門)
- JPA中EntityListeners注解的使用詳解
- php中html_entity_decode實(shí)現(xiàn)HTML實(shí)體轉(zhuǎn)義
- EF(EntityFramework) 插入或更新數(shù)據(jù)報(bào)錯(cuò)的解決方法
- 詳解ASP.NET中Identity的身份驗(yàn)證代碼
- c# 使用Entity Framework操作Access數(shù)據(jù)庫(kù)的示例
- Idea自動(dòng)生成Entity實(shí)現(xiàn)過(guò)程詳解
相關(guān)文章
增加asp.net應(yīng)用程序性能的20種方法(簡(jiǎn)單有效)
增加asp.net應(yīng)用程序性能的20種方法小結(jié),需要的朋友可以參考下,對(duì)于服務(wù)器也需要一些設(shè)置。2010-01-01
asp.net core webapi 服務(wù)端配置跨域的實(shí)例
下面小編就為大家分享一篇asp.net core webapi 服務(wù)端配置跨域的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
C# 調(diào)用存儲(chǔ)過(guò)程簡(jiǎn)單完整的實(shí)例代碼
自己copy過(guò)來(lái)的,忘了出處,一來(lái)分享,二來(lái)保存起來(lái),想學(xué)習(xí)c#與存儲(chǔ)過(guò)程結(jié)合使用的朋友可以參考下。2010-01-01
google suggest 下拉菜單實(shí)現(xiàn)代碼(asp.net版本)
原來(lái)發(fā)表過(guò),是asp版本的,但是不支持上下鍵,現(xiàn)在后臺(tái)處理程序用.net寫的。代碼進(jìn)行部分優(yōu)化。2009-07-07
MVC 5限制所有HTTP請(qǐng)求必須是POST方式
這篇文章主要為大家詳細(xì)介紹了MVC 5限制所有HTTP請(qǐng)求必須是POST方式的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
用javascript為DropDownList控件下拉式選擇添加一個(gè)Item至定義索引位置
用Javascript為DropDownList控件下拉式選擇添加一個(gè)Item至定義索引位置;準(zhǔn)備數(shù)據(jù),創(chuàng)建一個(gè)對(duì)象,將是存儲(chǔ)DropDownList控件每個(gè)Item數(shù)據(jù)2013-01-01
asp.net使用JS+form表單Post和Get方式提交數(shù)據(jù)
今天小編就為大家分享一篇關(guān)于asp.net使用JS+form表單Post和Get方式提交數(shù)據(jù),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01

