1. 程式人生 > >IdentityServer4之Implicit和純前端好像很配哦

IdentityServer4之Implicit和純前端好像很配哦

### 前言 上一篇[Resource Owner Password Credentials模式](https://mp.weixin.qq.com/s?__biz=MzU1MzYwMjQ5MQ==&mid=2247484469&idx=1&sn=27f55932d9d84644330c1c4400aa7ab2&chksm=fbf118e1cc8691f76f6ef3e44db8deb6497e85b46b7055cfdbd86a778ec459e55539d7ec7858&scene=21#wechat_redirect)雖然有使用者參與,但對於非信任的第三方的來說,使用這種模式是有風險的,所以相對用的不多;這裡接著說說**implicit隱式模式**,這種模式比較適合於純前端客戶端,比如Vue、Angular、React專案等,相對來說整個流程比較安全,只需在認證伺服器進行認證即可,無需在客戶端進行相關隱私資訊錄入,但前提是要客戶端保證安全,不然容易被別人釣魚(安全很重要),那IdentityServer4不背這個鍋。 ### 正文 既然有使用者參與,互動肯定少不了,認證那更不能缺少,所以這裡使用**OIDC(OpenID Connect)**的協議進行使用者身份驗證;別跑,不管是客戶端還是認證伺服器端,已經都封裝好了,拿過來直接用即可; 從流程先了解一下,直接上圖: ![image-20210126225530407](https://i.loli.net/2021/01/26/SY7ICKbo1cHMTQr.png) 流程簡要說明: 1. 使用者通過瀏覽器(**User-Agent**)訪問第三方客戶端(**Client**); 2. 如果客戶端需要進行認證授權,則將其重定向到認證伺服器(**Authorization server**); 3. 使用者(**ResorceOwner**)在認證伺服器上進行認證; 4. 認證伺服器(**Authorization server**)驗證成功之後,返回AccessToken和Id Token客戶端; 5. 後續使用者再操作客戶端的時候,若需訪問保護資源,直接在請求中帶上AccessToken即可; 6. 最終資源伺服器(**Resource server**)返回對應資訊; 術語解釋: - **User-Agent**:這裡指就是瀏覽器;如果客戶端是Web,就需要使用者通過瀏覽器訪問客戶端,所以這裡的瀏覽器就是User-Agent; - **Id Token**:標識使用者身份的Token,這是OpenID Connect帶上的。 知道大概的流程,接下來就通過程式碼實踐的方式演示一把。 #### 1.拷貝[上一節Reource Owner Password](https://mp.weixin.qq.com/s?__biz=MzU1MzYwMjQ5MQ==&mid=2247484469&idx=1&sn=27f55932d9d84644330c1c4400aa7ab2&chksm=fbf118e1cc8691f76f6ef3e44db8deb6497e85b46b7055cfdbd86a778ec459e55539d7ec7858&scene=21#wechat_redirect)的授權伺服器和資源伺服器程式碼並完善; 對於資源伺服器來說,這裡先暫時不用修改其他; **認證伺服器增加介面支援** 而認證伺服器需要有自己的頁面,因為在訪問客戶端時會重定向到認證伺服器進行認證資訊錄入和授權相關操作,那頁面需要自己寫嗎,不需要的,IdentityServer4模板中已經準備好了,如下操作: - 方式一:直接從github上下載,下載地址:https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/tree/main; - 方式二:命令列方式,從IdentityServer4模板中獲取; ```bash dotnet new -i IdentityServer4.Templates ##先安裝模板,裡面有很多關於IDS4的模板 dotnet new is4ui ## 指定UI模板獲取, ``` 通過以上兩種方式都可以獲取到以下檔案,將其拷貝到認證伺服器專案中,如下: ![image-20210126233703440](https://i.loli.net/2021/01/26/UtijTOAQmYW2LeB.png) 由於之前的認證伺服器只是單純API專案,不支援MVC,因為增加的介面是MVC頁面,所以需要在Startup.cs中增加MVC的支援,頁面中需要樣式檔案的載入,則同時需要增加靜態檔案處理,如下: ![image-20210126234143337](https://i.loli.net/2021/01/26/guqnTAFOmx3l5rD.png) 執行起來看效果,如下: ![image-20210128142756227](https://i.loli.net/2021/01/28/YBho3wXKMQ7SjvG.png) **備案客戶端** 上面介面沒問題了,這裡打算做一個純前端(Vue)的客戶端進行測試,所以需要在認證伺服器中提前將客戶端進行備案,如下: ![image-20210128164917702](https://i.loli.net/2021/01/28/x8y7f9beBCsjVFz.png) #### 2. 增加純前端客戶端(Vue) 這裡不打算使用腳手架工具去生成專案,為了不喧賓奪主,這裡就很單純的寫html和Js,只是在其中引用Vue,用Vue的思路進行編碼演示; 既然是個純前端專案,得要有個伺服器作為宿主,然後通過URL地址訪問頁面,這裡不想用其他比較重的伺服器,live-server簡單好用,就用它了,簡單搭建一下環境: **環境準備** 我是用npm安裝,所以需要安裝nodejs,這裡就不詳細擴充套件了,具體安裝步驟詳見:https://www.runoob.com/nodejs/nodejs-install-setup.html; 有了nodejs環境,直接npm安裝live-server,如下命令: ```bash npm install -g live-server ###全域性安裝live-server,後續都可以用 ``` 安裝完就可以直接使用了,直接在指定目錄下執行live-server即可,預設埠是8080; **建立純前端客戶端** 專案目錄結構如下: ![image-20210128090826761](https://i.loli.net/2021/01/28/TzOvnQu7yMx2mdC.png) 簡要說明: - **js**目錄:存放依賴的js; **live-server-https**目錄是提供live-server啟動時提供live-server-https支援,其實專案本身並不需要;後續如果需要將前端頁面指定https訪問,可以指定此庫執行; **oidc-client.js/oidc-client.min.js**是用於前端客戶端實現OpenID Connect,引入直接使用即可,也可以自行在網上下載(https://github.com/IdentityModel/oidc-client-js); **vue.js**提供vue的支援,雖然沒用腳手架,但用vue還是沒問題; - **callback.html**登入成功之後回撥的頁面,即當在認證伺服器登入成功之後重定向客戶端的頁面; - **index.html**主頁面,這裡也用於登出時重定向的頁面; - **noauth.html**無許可權時跳轉的頁面; 程式碼主要集中在index.html,下面直接上程式碼吧,具體說明直接看註釋吧; **index.html程式碼**: ```html
{{results}}
``` **callback.html程式碼**: ```html ``` **noauth.html程式碼**: ```html 沒許可權 ``` 到這客戶端的程式碼已經擼完了,直接進入JsClient目錄,執行live-server即可: 如果使用http請求,執行```live-server```即可; ![image-20210128144000642](https://i.loli.net/2021/01/28/uZJebkaXotUNFRn.png) #### 3.聯合除錯看效果 上一步已經將客戶端啟起來了,接下來把認證伺服器和API資源伺服器啟動,看看效果: 1. 點選Login進行登入,就會跳轉到認證伺服器進行驗證,如下: ![image-20210128095837259](https://i.loli.net/2021/01/28/yliULaYQtx3w4FA.png) 到這一步,估計用其他瀏覽器沒什麼問題,會繼續進行跳轉;但如果用到谷歌最新的瀏覽器,這裡就不會跳轉,因為谷歌對Cookie進行整改,儘管輸入正確的使用者名稱和密碼,也只是重新整理一下,還是在登入頁面,需要做一下處理,如下: 新增一個處理類:SameSiteCookiesServiceCollectionExtensions.cs,程式碼內容就不貼啦,這是公開程式碼,大佬寫好的解決方案; 寫好處理類之後,直接使用即可,如下: ![image-20210128164529597](https://i.loli.net/2021/01/28/CDup4o7Nq5B3Kz9.png) 完成以上步驟,谷歌不能跳轉的問題就解決啦; 繼續往下走; 2. 輸入使用者名稱和密碼 Zoe/123456,點選登入,直接進入授權選擇頁面,如下: ![image-20210128100216860](https://i.loli.net/2021/01/28/HYe4JrmzXIQBFLP.png) 這個介面是不是比較熟,通常我們用微信、QQ或者是其他登入時,都會彈出一個授權頁面選擇授權內容。這個授權頁面是可以控制不顯示的,只需要在認證伺服器備案客戶端時設定屬性即可,如下: ![image-20210128165114127](https://i.loli.net/2021/01/28/yqe73xc4m6iFSHY.png) 3. 點選授權完成之後,就會重定向配置的callback.html頁面,在callback.html程式碼中可以看到,如果判斷使用者已經登入,就直接轉到index.html主頁面,否則就轉到noauth.html無許可權頁面,這裡已經登入授權成功,肯定最終就轉到index.html頁面,如下: ![image-20210128100623208](https://i.loli.net/2021/01/28/YF1vsDe8knAupS5.png) 4. 點選CallAPI去呼叫受保護資源,內部是根據上一步得到AccessToken進行保護資源的訪問; 注意,這裡資源伺服器一定要進跨域配置,允許客戶訪問,在API資源伺服器中進行如下配置: ![image-20210128202338913](https://i.loli.net/2021/01/28/knwx9h1JbemNyVK.png) 然後執行效果如下: ![image-20210128165434044](https://i.loli.net/2021/01/28/NBmluwAZDRYCiap.png) 5. 點選Logout登出,這裡不截圖了,小夥伴試試; 好吧,今天狀態不佳,先到這,後續專案實戰再好好說說。 原始碼地址:https://github.com/zyq025/IDS4Demo/tree/main/ImlicitDemo; ### 總結 Implicit模式使用思路差不多就是這樣,但這種模式特別要注意專案本身安全,如資料傳輸過程被攔截,或網站本身容易被攻擊,黑客通過釣魚頁面就容易獲取隱私資訊等,所以專案通常都強烈推薦https,降低資料傳輸過程被抓包的風險;而對於釣魚等這種攻擊,可以通過判斷校驗源IP等方式;安全的點很多,這裡只是簡單舉例;下次說說**Authorization Code(授權碼)**模式; 一個被程式搞醜的帥小夥,關注"Code綜藝圈",跟我一起學~ ![](https://i.loli.net/2021/01/07/l7e8dBOT4acF