Nacos自開源依賴,權限控制一直需求比較強烈,這也反應了用戶需求將Nacos部署到生產環境的需求。最新發布的Nacos 1.2.0版本已經支持了服務發現和配置管理的權限控制,保障用戶安全上生產。本文主要介紹Nacos權限控制的設計方案和使用指南。java
在分佈式服務調用時,須要對未知的或者不受信任的請求來源的請求進行識別和拒絕。權限控制通常分爲兩個階段:身份識別(Authentication)和權限識別(Authorization)。身份認證主要肯定訪問者的身份,權限識別則判斷這個訪問者是否有對應資源的權限。mysql
在Nacos的場景中,配置管理的權限控制指的是設置某個配置可否被某個用戶讀寫,這個比較好理解,沒有權限的用戶舊沒法讀取或者寫入對應的配置。服務發現的權限控制指的是用戶是否有權限進行某個服務的註冊或者訂閱,這裏須要注意的是服務發現的權限控制只可以控制用戶是否能夠從Nacos獲取到服務的地址或者在Nacos上修改服務的地址。可是若是已經獲取到了服務的地址,Nacos沒法在服務真正調用時進行權限控制,這個時候的權限控制須要由服務框架來完成。git
Nacos的權限控制,目標是可以知足用戶基本的鑑權需求,同時可以保持擴展性,能夠支持去對接用戶自帶的用戶管理系統或者鑑權系統,包括後面和K8S生態以及Service Mesh生態可以無縫的融合。基於這樣的考慮,目前Nacos權限控制的設計是自帶一個基本的實現,而後能夠支持用戶擴展。具體的設計以下。github
總體的模塊設計是儘可能將鑑權的邏輯抽象出來,不在服務發現模塊或者配置管理模塊添加相關的邏輯。經過配置文件能夠選擇當前使用的鑑權系統。Nacos自帶的認證系統使用JWT Token,自帶的鑑權系統使用的是RBAC。算法
對於用戶來講,不論是在控制檯仍是在客戶端,都是上傳用戶名和密碼來獲取一個token,而後後續的每一次到Nacos的請求都會帶上這個token來代表身份。這個token會有一個失效時間,對於控制檯來講,只須要直接提示用戶從新登陸便可,對於客戶端則須要有一個按期到Nacos刷新token的邏輯。sql
Nacos自帶的鑑權系統使用的是RBAC模型,能夠在網上查詢相關的資料。數據庫
鑑權的數據模型也是基於標準的RBAC來設計的,分爲用戶、角色和權限三部分。用戶就是由用戶名和密碼組成的用戶信息,角色則是一個邏輯上的用戶組,Nacos啓動時會自帶一個全局管理員的角色,只有這個全局管理員的角色能夠進行添加用戶、添加角色、添加受權等操做,保證安全性。而權限則是由資源+動做來組成。json
如下接口涉及到登陸和鑑權的全部邏輯,這些接口除了登陸接口,其餘接口都只能由全局管理員來調用。瀏覽器
/nacos/v1/auth/users?username=xx&password=yy緩存
/nacos/v1/auth/users/login?username=xxx&password=yyy
mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
nacos.core.auth.enabled=true
這個開關採用了熱加載模式,無需重啓Server便可生效。所以當權限控制功能使用有異常時,能夠直接回滾到不鑑權的模式。
一、使用管理員帳號登陸Nacos控制檯(若是頁面提示錯誤,能夠狀況瀏覽器緩存刷新頁面):
能夠看到,左側邊欄增長了一個父菜單和三個子菜單,分別用於權限控制裏的用戶建立、角色建立以及權限管 理。這個菜單欄只會在管理員登陸的時候顯示,也就意味着只有管理員才能進行權限的管理和分配。
二、管理用戶。點擊「用戶列表」,進入用戶管理頁面,能夠進行用戶的建立、修改和刪除:
三、管理角色。由於Nacos的自帶的權限是基於角色來進行分配的,所以須要給建立好的用戶綁定一些角色:
四、管理權限。角色建立好之後,就能夠給這個角色賦予特定的權限了:
在「添加資源」對話框裏,能夠選擇綁定的角色,命名空間資源以及對應的動做類型,例如在上圖中,咱們給角色role1綁定命名空間test的讀寫權限。而後又由於剛剛咱們是將user1綁定到了role1上,那麼user1這個用戶就能夠對test這個命名空間的資源進行讀寫操做了。
五、使用user1登陸控制檯。點擊控制檯右上角,退出admin帳號,而後用剛纔建立的user1進行登陸:
如上圖所示,首先是左側的權限管理菜單消失了,由於當前用戶不是管理員。其次是會彈出一個鑑權失敗的提示框。不用擔憂,這個提示框意思是user1沒有public命名空間的讀權限,因此會彈出,可是不影響咱們將命名空間切換到test:
如上圖所示,咱們能夠看到test命名空間的配置數據了,下面咱們再來介紹客戶端的使用。
六、首先依賴最新的nacos 1.2.0客戶端,而後在初始化時添加以下代碼:
Properties properties = new Properties(); properties.put(PropertyKeyConst.NAMESPACE, "99a791cf-41c4-4535-9e93-b0141652bad0"); properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:8848"); // 配置用戶名: properties.put(PropertyKeyConst.USERNAME, "user1"); // 配置密碼: properties.put(PropertyKeyConst.PASSWORD, "pwd1"); ConfigService iconfig = NacosFactory.createConfigService(properties);
七、使用客戶端進行正常的讀寫配置操做。