日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于微服务API级权限的技术架构

發布時間:2023/12/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于微服务API级权限的技术架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一般而言,企業內部一套成熟的權限系統,都是基于角色(Role)的 訪問控制方法(RBAC – Role Based Access Control),即權限 (Permission)與角色相關聯,用戶(User)通過成為適當角色的成員而得到這 些角色的權限,權限包含資源(或者與操作組合方式相結合),最終實現權限控制 的目的。

背景

權限系統是根據系統設置的安全規則或者安全策略,用戶可以訪問而且只能訪問自己被授權的資源。

一般而言,企業內部一套成熟的權限系統,都是基于角色(Role)的訪問控制方法(RBAC – Role Based Access Control),即權限(Permission)與角色相關聯,用戶(User)通過成為適當角色的成員而得到這些角色的權限,權限包含資源(或者與操作組合方式相結合),最終實現權限控制的目的。

一言以蔽之,基于角色的訪問控制方法的訪問邏輯表達式為“Who對What(Which)進行How的操作”,它的由內到外的邏輯結構為權限->角色->用戶,即一個角色對應綁定多個權限,一個用戶對應綁定多個角色,這也是秦蒼基礎架構部對于公共權限服務實現的基本指導思想。

權限服務與基礎架構部其他公共服務的關系圖

一.API權限定義、入庫和攔截

對于API權限,我們實行基于注解(Annotation)的掃描入庫和攔截,不需要業務服務自行在界面上錄入

1、權限定義

API權限以每個接口或者實現類中的方法作為權限資源,每個權限和微服務名(Service Name)掛鉤。

我們通過在業務服務的API上添加注解的方式,進行權限定義。基礎架構部會提供一個權限組件(Permission Component)Jar給業務服務部門,里面包含了自定義的注解,這樣的實現方式,對業務服務的影響非常小,增加權限機制只是在代碼層面加幾個注解而已。具體使用方式如下

對于一個普通的接口類,我們可以這樣定義:

1 2 3 4 5 6 7 8 @Group(name = "User Permission Group", label = "用戶權限組", description = "用戶權限組") public interface UserService { @Permission(name = "Add User", label = "添加用戶") boolean addUser(@UserId String userId, User user); @Permission(name = "Delete User", label = "刪除用戶", description = "刪除用戶") boolean deleteUser(@UserId String userId, User user); }

對于通過Swagger方式暴露出去的API,我們可以這樣定義:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Path("/user") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Api(value = "User resource operations") @Group(name = "User Permission Group", label = "用戶權限組", description = "用戶權限組") public interface UserService { @GET @Path("/addUser/{userId}") @Permission(name = "Add User", label = "添加用戶") boolean addUser(@PathParam("userId") @UserId String userId, User user); @POST @Path("/deleteUser/{userId}") @Permission(name = "Delete User", label = "刪除用戶", description = "刪除用戶") boolean deleteUser(@PathParam("userId") @UserId String userId, User user); }

在上述簡短的代碼中,我們可以發現有三個自定義的注解,@Group、@Permission和@UserId。

  • @Permission,即為每個API(接口方法)定義一個權限,要求有name(英文格式),label(中文格式)和description(權限描述)
    • @Group,即定義的權限歸屬哪個權限組,考慮到一個接口中包含很多個API,接口數目又比較多,那么我們可以為每個接口下的所有方法歸為一個組。業務服務可自行定義權限組,也可以選擇不定義,那么會歸屬到默認預定義的權限組中
  • l@UserId,即業務服務需要在他們的API上加入用戶ID的參數,當AOP切面攔截做權限驗證時候,用戶ID是需要傳入的必要參數

2、權限入庫和攔截

當API權限定義好以后,我們在權限組件里面加入掃描權限入庫和攔截的算法。采用Spring AutoProxy自動代理的框架來實現我們的掃描算法。

2.1 創建PermissionInterceptor.java繼承org.aopalliance.intercept.MethodInterceptor,步驟如下

  • 實現Object invoke(MethodInvocation invocation)方法,獲取注解值
  • 根據不同注解進行不同的切面攔截,實現對@Group,@Permission和@UserId三個注解的權限攔截邏輯

2.2 創建PermissionAutoProxy.java繼承Spring的org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator類,步驟如下

  • 在構造方法里設置好Interceptor通用代理器(即實現了MethodInterceptor接口的攔截類PermissionInterceptor.java)
  • shouldProxyTargetClass用來決定是接口代理,還是類代理。在權限定義的時候,其實我們還支持把注解加在實現類上,而不僅僅在接口上,這樣靈活運用注解放置的方式-
  • getAdvicesAndAdvisorsForBean是最核心的方法,用來決定哪個類、哪個方法上的注解要被掃描入庫,也決定哪個類、哪個方法要被代理。如果我們做的更加通用一點,那么可以抽象出三個方法,供getAdvicesAndAdvisorsForBean調用
1 2 3 4 5 6 7 8 // 返回攔截類,攔截類必須實現MethodInterceptor接口,即PermissionInterceptor protected abstract Class<? extends MethodInterceptor> getInterceptorClass(); // 返回接口或者類的方法名上的注解,如果接口或者類中方法名上存在該注解,即認為該接口或者類需要被代理 protected abstract Class<? extends Annotation> getMethodAnnotationClass(); // 掃描到接口或者類的方法名上的注解后,所要做的處理 protected abstract void methodAnnotationScanned(Class<?> targetClass);

2.3 創建PermissionScanListener.java實現Spring的org.springframework.context.ApplicationListener.ApplicationListener接口,步驟如下

  • 在onApplicationEvent(ContextRefreshedEvent event)方法里實現入庫代碼
  • 在微服務的Spring容器啟動的時候,將自動觸發權限數據入庫的事件

    通過上述闡述,我們就實現了權限的掃描入庫和攔截

二、API權限所對應的角色(Role)管理

角色是一組API權限的匯總,每個角色也將和微服務名掛鉤。角色組的作用是為了匯總和管理眾多的角色

角色管理需要人工在界面上進行操作,角色管理分為角色組增刪改查,以及每個角色組下的角色增刪改查

三、 API權限所屬的角色和用戶(User)的綁定

權限不能直接和用戶綁定,必須通過角色作為中間橋梁進行關聯。那么我們要實現

  • 角色與權限的綁定,即一個角色和多個權限的關聯
  • 用戶與角色的綁定,即一個用戶和多個角色的關聯

角色和權限的綁定頁面

?

用戶和角色的綁定頁面 </center

?

四、權限系統驗證方式

1、API接入的驗證方式

通過遠程RPC方式的調用

1.1 掃描接入Permission組件的API Resource

1 2 3 4 5 6 7 @Configuration @ComponentScan(basePackages = { "com.omniprimeinc.service.myservice " }) @Import({ com.omniprimeinc.commonservice.permission.api.config.Config.class, com.omniprimeinc.commonservice.permission.annotations.config.Config.class }) public class Config { }

1.2 通過API Resource去調用RPC接口獲取驗證結果

1 2 3 4 5 6 7 8 9 @Path("/authorization") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Api(value = "Authorization resource operations") public interface AuthorizationResource { @GET @Path("/authorize/{userId}/{permissionName}/{serviceName}") Boolean authorize(@PathParam("userId") String userId, @PathParam("permissionName") String permissionName, @PathParam("serviceName") String serviceName); }

2、Rest調用的驗證方式

http://host:port/authorization/authorize/{userId}/{permissionName}/{serviceName}

通過User ID、Permission Name(權限名,映射于對應的方法名)、Service Name(應用名)來判斷是否被授權,返回結果是true或者false

五、權限服務和用戶服務的整合

用戶服務即整合了Ldap系統的用戶和橋接業務用戶系統

權限服務接入用戶服務后,可以在權限授權頁面上選取相應的用戶進行權限授權

六、權限服務的安全控制

未來規劃,服務之間的調用增加如下機制

  • 黑/白IP名單機制。當A服務調用B服務的時候,B服務會實現維護一個黑/白IP列表,表示B服務只允許在某個IP網段的A服務才能有權限調用B服務
  • 服務間約定的SecretKey。當A服務調用B服務的時候,兩個服務之間實現實現約定API訪問密鑰,此密鑰不能輕易泄密。這樣就規避了B服務被模擬Rest請求調用(例如通過PostMan調用)
  • 服務的API簽名。當A服務調用B服務的時候,A服務需要獲得正確的B服務API的簽名,才有權限去調用

http://blog.springcloud.cn/sc/mfw-jq/

?

總結

以上是生活随笔為你收集整理的基于微服务API级权限的技术架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。