這個系列文章介紹的是Identity Server 4 的 Hybrid Flow, 前兩篇文章介紹瞭如何保護MVC客戶端, 本文介紹如何保護API資源.html
保護MVC客戶端的文章: http://www.javashuo.com/article/p-spxopsak-by.html, http://www.javashuo.com/article/p-dwismktz-w.htmlgit
相關代碼: https://github.com/solenovex/Identity-Server-4-Tutorial-Code 裏面03那部分.github
回顧一下該項目使用的流程api
圖裏有IDP (Identity Provider, 我例子裏是用Identity Server 4構建的項目)和客戶端(個人例子裏是MVC客戶端).ide
在上面流程走完以後, MVC客戶端得到了Access Token, MVC客戶端驗證Access Token併成功後, 就可使用Access Token來訪問被保護的API資源了, 而Access Token會在被保護的API那裏再次進行驗證.測試
首先在IDP裏配置一個返回ApiResoruce的方法:ui
和IdentityResource相似, ApiResource就是與API相關的scopes.3d
在Client配置那裏, 把這個ApiResource的名字添加到容許的scopes裏:rest
最後在IDP的startup裏, 註冊ApiResources:server
如今來到MVC客戶端這裏, 須要把上面的scope添加上:
最後來到API項目, 首先確保使用HTTPS:
API項目還須要安裝IdentityServer4.AccessTokenValidation這個包, 能夠經過Nuget安裝.
安裝後, 還須要進行配置 (官方文檔: https://identityserver4.readthedocs.io/en/release/quickstarts/1_client_credentials.html#adding-an-api):
其中IdentityServerAuthenticationDefaults.AuthenticationScheme 就是 「Bearer」 的意思, 這裏使用的就是這個方案.
AddIdentityServerAuthentication()方法註冊了Access Token 驗證的處理者. 裏面Authority就是IDP的URI, ApiName就是IDP裏配置的API的名字.
在Startup的Configure方法裏, 還須要把它添加到管道:
要確保它在UseMVC以前調用.
我在API項目裏使用過濾器爲全部的Controller都加上了受權過濾:
固然也能夠在具體的Controller或Action級寫上這個:
不管如何如今訪問Country資源是須要受權的.
回到MVC客戶端, 在Home的Contact Action裏調用CountryAPI資源:
下面測試一下未使用Access Token訪問被保護的Country資源的狀況, 從新操做能夠看到用戶贊成受權頁面出現了剛纔配置的API資源名:
在訪問Contact頁面的時候, 提示未受權:
那就用以前介紹過的方法來獲取Access Token並設置Authorization Header爲 「Bearer [AccessToken]」 便可:
再修改一下Contact頁面, 顯示Access Token:
從新操做, 就能夠看到Country資源數據了:
去jwt.io對Access Token進行解碼:
看一下aud (audience, 觀衆) 這個屬性, 它有兩個值, 第一個是指IDP那邊對資源 (調用用戶信息端點), 第二個就是指API那個項目.
這個屬性說明這個access token是爲它們倆準備的.
而scope裏面的「restapi」就是aud裏面的「restapi」, 因此這個token容許被用來訪問咱們的「restapi」.
而scope裏面的「profile」等scopes是對應另外一個aud的值, 這些scopes來自IDP那裏.
如今Access Token有這些claims, API也就能獲得這些claims, 可是有時API還須要用戶身份相關的claims.
修改IDP的ApiResource配置便可:
再次操做後, 查看token, 就能夠看到我剛剛添加的那兩個claim了:
而role這個claim, 在API裏是能夠被識別成角色的, 若是我在API的Action上設置權限以下:
那麼, Nick這個用戶就能夠獲得Country數據, 而Dave則會顯示403 Forbidden: