漫步SpringSecurity---小短文搞懂分佈式中的單點登錄、JWT與RSA是個啥?

基本上每一個系統都會有一個認證功能,這個認證功能其實就是我們平時所做的登錄。用戶通過輸入自己的用戶名和密碼,我們後臺查詢數據庫,如果輸入都正確,那麼就給你登錄進入系統,同時後端保存下session信息。反之如果用戶名或密碼不正確則告訴用戶登錄失敗。今天介紹的兩位主角(JWT、RSA)就和認證有關


這一篇沒有代碼。

平時我們自己寫登錄功能的話,業務邏輯就是上面說的那樣。可是現在我們介紹的Security已經寫好了認證的功能,我們只需要引入依賴,稍作配置就可以"開箱即用"了。

這裏現在的Java web應用一般分爲兩種,一種就是傳統開發,一種是分佈式開發。認證的的場景也是分爲這兩種。

傳統開發

先說一下傳統開發,傳統開發就是我們基本做的項目,所有的業務、controller、DAO、配置文件、前端頁面、各種靜態資源...都堆在一個工程中,並把它們統一打成一個jar/war在發佈到線上。

這時我們的登錄邏輯,也比較簡單,就是判斷用戶名和密碼是否正確,正確則保存session信息,錯誤,則轉發回登錄頁,並要求重新登錄。

但是某一天系統流量大了之後,一個服務器扛不住了怎麼辦,就比如淘寶,雙11或618,一瞬間的高併發訪問量,不僅網站資源承受高併發訪問,認證功能這裏也是,想想一下子也會有很多用戶進行訪問,這樣單個服務器也會面臨死機的風險。

接下來針對這種情況,我們就介紹今天的主角們登場了。

分佈式開發

簡單先介紹一下分佈式開發,這個在之前的博客中也有記錄到,就是把各種模塊都打散,比如用戶模塊放到一個服務器,訂單模塊放到另外一個服務器等等。認證模塊也是同理,將認證相關的模塊單獨放到一個服務器中。這麼可以提高耦合性,同時提高了容錯率,可以面對高併發的場景。。

但是有一個問題,認證模塊單獨佔一個服務器,那麼假設用戶登錄成功之後,我們把用戶信息保存至session中,接着用戶訪問別的模塊,由於它們不是在同一臺服務器上,那麼session是不能共享的。別的模塊怎麼判斷你是否登錄了呢?

有些朋友可能會想到一個東西叫global-session,它的確可以共享session,但是今天不是用這個。這裏就要介紹第一個主角:

分佈式開發中的單點登錄

單點登錄的實現分兩大環節:

  • 用戶認證: 這一環節主要是用戶向認證服務器發起認證請求,認證服務器給用戶返回一個成功的令牌token,
    主要在認證服務器中完成,即圖中的A系統,注意A系統只能有一個。

  • 身份校驗: 這一環節是用戶攜帶token去訪問其他服務器時,在其他服務器中要對token的真僞進行檢驗,主
    要在資源服務器中完成,即圖中的B系統,這裏B系統可以有很多個。

在這裏插入圖片描述

這裏的關鍵就是token,在A服務器中登錄成功拿到token後,返回給用戶,然後用戶訪問別的服務器時就需要帶着這個token了。

接着有情第二位主角:

JWT

從分佈式認證流程中,我們不難發現,這中間起最關鍵作用的就是token,token的安全與否,直接關係到系統的健壯性,這裏我們選擇使用JWT來實現token的生成和校驗。

JWT,全稱JSON Web Token,官網地址https://jwt.io,是一款出色的分佈式身份校驗方案。可以生成token,也可以解析檢驗token。

它其實就是在分佈式的環境中負責token的生成和驗證的。

JWT生成的token由三部分組成:

  • 頭部: 主要設置一些規範信息,簽名部分的編碼格式就在頭部中聲明。

  • 載荷:token中存放有效信息的部分,比如用戶名,用戶角色,過期時間等,但是不要放密碼,會泄露!

  • 簽名:將頭部與載荷分別採用base64編碼後,用“.”相連,再加入鹽,最後使用頭部聲明的編碼類型進行編
    碼,就得到了簽名。

從JWT生成的token組成上來看,要想避免token被僞造,主要就得看簽名部分了,而簽名部分又有三部分組成,其中頭部和載荷的base64編碼,幾乎是透明的,毫無安全性可言,那麼最終守護token安全的重擔就落在了加入的鹽上面了!

試想:**如果生成token所用的鹽與解析token時加入的鹽是一樣的。豈不是類似於中國人民銀行把人民幣防僞技術公開了?**大家可以用這個鹽來解析token,就能用來僞造token。

這時,我們就需要對鹽採用非對稱加密的方式進行加密,以達到生成token與校驗token方所用的鹽不一致的安全效果!

而這個非對稱加密,就是第三位主角:

RSA

  • 基本原理:同時生成兩把密鑰:私鑰和公鑰,私鑰隱祕保存,公鑰可以下發給信任客戶端

  • 優點:安全,難以破解

  • 缺點:算法比較耗時,爲了安全,可以接受

  • 歷史:三位數學家Rivest、Shamir 和 Adleman 設計了一種算法,可以實現非對稱加密。這種算法用他們三
    個人的名字縮寫:RSA。

這個非對稱加密有分爲兩種:

  1. 私鑰加密,持有私鑰或公鑰纔可以解密
  2. 公鑰加密,持有私鑰纔可解密

我們一般使用的是私鑰加密,爲什麼呢?

這裏試想一下,如果我們分佈式系統中,在認證模塊裏通過公鑰加密後,那麼別的模塊只能放置私鑰了。如果有人做壞事,他自己拿公鑰加密(公鑰是暴露的),那麼加密出來,他可以直接拿去訪問別的模塊,從而不用登錄。那這個RSA算法就是形同虛設了。

這時候換成私鑰加密,別的模塊放置公鑰,如果別人拿公鑰(他只能拿公鑰)僞造加密,那別的模塊因爲放置的是公鑰的,也解密不了,所以僞造失敗。

平時我們用到的還是私鑰加密


今天就記錄到這裏,後續會接着記錄Security的相關知識。幫到忙的話就多多關注下我哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章