Identity Server 4 - Hybrid Flow - Claims
前一篇?Identity Server 4 - Hybrid Flow - MVC客戶端身份驗證:?https://www.cnblogs.com/cgzl/p/9253667.html
Claims
我不知道怎么樣翻譯這個詞比較好, 所以我一般就不翻譯了.
在前一篇文章里, MVC客戶端配置身份認證的時候有這么一句話(Startup的ConfigureServices):
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
官方文檔是這樣介紹的: “我們關閉了JWT的Claim 類型映射, 以便允許well-known claims.”
如果我把這句話刪掉, 然后再看看User.Claims的類型和值:
現(xiàn)在有些claim的類型與ID Token里面的類型名稱是不一樣, 也有一些claim不見了:
?
而加上這句話之后, 現(xiàn)在User claim類型的名字就和ID Token里面一樣了:
?
再看一下ID Token:
有一些claims并沒有出現(xiàn)在User.Claims里面. 這是因為這個中間件默認情況下會過濾掉一些它認為我們不需要的claim, 例如nbf, amr等.
就先看下面這兩種情況吧:
1. 避免claims被默認過濾掉
如果我想讓中間件不要過濾掉nbf和, 也就是把nbf和amr從被過濾掉集合里移除, 就可以使用這個方法:
然后再看About頁面打印的UserClaims:
這樣nbf和amr就不會被過濾掉了(從過濾掉的集合移除了).
?
2. 刪除某些Claims
假如說我這個MVC客戶端不需要sid和idp, 那么我可以使用下面的方法:
?
這是一個擴展方法, 一定要注意它和Remove方法的區(qū)別.........
?
再次操作后, 可以看到這些Claims不見了:
?
ClaimActions還有其他幾個方法, 請自行探索.
?
用戶信息端點 UserInfo Endpoint?
盡管ID Token里面可以包含很多用戶的claims, 但是盡量讓ID Token小一點比較好. 所以當MVC客戶端需要更多用戶信息的時候可以手動請求用戶信息端點, 這樣做也可以獲得用戶最新的其他信息.
UserInfo Endpoint的官方文檔在這:?http://openid.net/specs/openid-connect-core-1_0.html#UserInfo
它要求使用GET或者POST進行請求, 但建議使用GET. 此外請求還需要使用Access Token.
這是一個例子:
成功請求的響應結果是一個JSON對象.
?
首先在IDP里面再添加一個email scope:
然后在配置的Client里面添加這個scope:
?
最后為TestUser添加email的claim:
?
回到MVC客戶端的Startup, 這里也需要添加email這個scope,
而且還要保證這個email不會出現(xiàn)在claims Identity里面, 這樣我在請求用戶信息端點的時候才會得到email而不是從User.Claims里面得到:
?
再次操作后, 可以看到User.Claims里沒有出現(xiàn)email:
?
下面我需要手動發(fā)送請求到用戶信息端點來獲取其他信息:
identity sever 4的這部分文檔在:?https://identityserver4.readthedocs.io/en/release/endpoints/userinfo.html#identitymodel,?https://github.com/IdentityModel/IdentityModel2
文檔提到, 需要為MVC客戶端安裝IdentityModel這個庫:
dotnet add package IdentityModel隨后, 我把獲取用戶email的代碼還是放在About Action里:
首先通過IDP的URI獲得discovery document, 然后從中取出UserInfo端點, 從Cookie里得到access token, 并用access token從用戶信息端點獲得claims, 從這些claims里面取得email并傳遞到About.cshtml.
相應的修改一下About.html:
?
重新操作后看About頁面:
?
對MVC客戶端使用基于角色對授權
首先需要在IDP那里對兩個用戶添加role這個claim:
分別是管理員角色和注冊用戶角色.
?
OpenID Connect并沒有定義關于角色role相關的scope, 所以我還需要自定義一個scope:
第一個參數(shù)是scope的名字, 第二個參數(shù)是scope的顯示名, 第三個參數(shù)是它所包含的claim類型, 這里就是“role”.
?
然后還需要客戶端允許請求“roles”這個scope:
?
IDP這邊配置完了, 下面是MVC客戶端的配置, 打開MVC的startup, 添加“roles”這個scope:
?
下面測試, 可以看到在同意頁面確實請求了角色“roles”這個scope:
?
然后同意后卻無法從User.Claims里看到角色role 這個claim:
這是因為ASP.NET默認對UserInfo返回的JSON數(shù)據(jù)里一些常用的頂層claim進行了映射, 以便它們能夠出現(xiàn)在User.Claims里面.
我也只需要把JSON里面的role claim, 映射到User.Claims里即可:
?
再次操作后, 就可以在User.Claims看到角色了:
?
然后我便可以在MVC客戶端的任意地方通過角色來控制用戶的訪問權限了, 例如:
但是如何把role claim映射成ASP.NET Core MVC可以識別的角色Roles呢?
可以在MVC里這樣配置:
該參數(shù)主要是配置驗證Token的一些東西, 然而它還可以指定客戶端的Name 和 Role Claim的類型.
?
操作后用兩個用戶分別測試一下, Nick 管理員, 可以訪問About:
?
另一個用戶, Dave 注冊用戶, 則不可以訪問About:
?
這說明角色已經被MVC客戶端識別了.
?
但是對于Dave這個用戶來說, 沒有權限訪問About時, 頁面顯示非常不友好, 所以下面解決這個問題.
首先建立一個AuthroizationController:
?
然后建立相關的view:
?
最后在Startup里面配置, 如果沒有權限就跳轉到這個Action上:
?
再次操作后, Dave點擊About后就會因為權限不足而跳轉到該頁面:
?
今天先到這, 我自己幾乎不用MVC, 我主要是做Web API的, 這部分的內容大部分來自官方文檔和其他一些資料綜合出來的.
代碼:?https://github.com/solenovex/Identity-Server-4-Tutorial-Code?02部分
相關文章:
要用Identity Server 4 -- OAuth 2.0 超級簡介
Identity Server 4 預備知識 -- OpenID Connect 簡介
Identity Server 4 - Hybrid Flow - MVC客戶端身份驗證
原文地址:https://www.cnblogs.com/cgzl/p/9268371.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的Identity Server 4 - Hybrid Flow - Claims的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core开发日志——Middl
- 下一篇: 微软宣布ASP.NET Core 2.0