Identity Server 4 - Hybrid Flow - Claims

前一篇 Identity Server 4 - Hybrid Flow - MVC客戶端身份驗證: http://www.javashuo.com/article/p-spxopsak-by.htmlhtml

Claims

我不知道怎麼樣翻譯這個詞比較好, 因此我通常就不翻譯了.git

在前一篇文章裏, MVC客戶端配置身份認證的時候有這麼一句話(Startup的ConfigureServices):github

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

官方文檔是這樣介紹的: 「咱們關閉了JWT的Claim 類型映射, 以便容許well-known claims.」ide

若是我把這句話刪掉, 而後再看看User.Claims的類型和值:測試

如今有些claim的類型與ID Token裏面的類型名稱是不同, 也有一些claim不見了:spa

 

而加上這句話以後, 如今User claim類型的名字就和ID Token裏面同樣了:.net

 

再看一下ID Token:翻譯

有一些claims並無出如今User.Claims裏面. 這是由於這個中間件默認狀況下會過濾掉一些它認爲咱們不須要的claim, 例如nbf, amr等.3d

就先看下面這兩種狀況吧:code

1. 避免claims被默認過濾掉

若是我想讓中間件不要過濾掉nbf和, 也就是把nbf和amr從被過濾掉集合裏移除, 就可使用這個方法:

而後再看About頁面打印的UserClaims:

這樣nbf和amr就不會被過濾掉了(從過濾掉的集合移除了).

 

2. 刪除某些Claims

假如說我這個MVC客戶端不須要sid和idp, 那麼我可使用下面的方法:

 

這是一個擴展方法, 必定要注意它和Remove方法的區別.........

 

再次操做後, 能夠看到這些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不會出如今claims Identity裏面, 這樣我在請求用戶信息端點的時候纔會獲得email而不是從User.Claims裏面獲得:

 

再次操做後, 能夠看到User.Claims裏沒有出現email:

 

下面我須要手動發送請求到用戶信息端點來獲取其餘信息:

identity sever 4的這部分文檔在: https://identityserver4.readthedocs.io/en/release/endpoints/userinfo.html#identitymodelhttps://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:

第一個參數是scope的名字, 第二個參數是scope的顯示名, 第三個參數是它所包含的claim類型, 這裏就是「role」.

 

而後還須要客戶端容許請求「roles」這個scope:

 

IDP這邊配置完了, 下面是MVC客戶端的配置, 打開MVC的startup, 添加「roles」這個scope:

 

下面測試, 能夠看到在贊成頁面確實請求了角色「roles」這個scope:

 

而後贊成後卻沒法從User.Claims裏看到角色role 這個claim:

這是由於ASP.NET默認對UserInfo返回的JSON數據裏一些經常使用的頂層claim進行了映射, 以便它們可以出如今User.Claims裏面.

我也只須要把JSON裏面的role claim, 映射到User.Claims裏便可:

 

再次操做後, 就能夠在User.Claims看到角色了:

 

而後我即可以在MVC客戶端的任意地方經過角色來控制用戶的訪問權限了, 例如:

可是如何把role claim映射成ASP.NET Core MVC能夠識別的角色Roles呢?

能夠在MVC裏這樣配置:

該參數主要是配置驗證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部分

相關文章
相關標籤/搜索