国产成人精品亚洲777人妖,欧美日韩精品一区视频,最新亚洲国产,国产乱码精品一区二区亚洲

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring Security 中細(xì)化權(quán)限粒度的方法

瀏覽:166日期:2023-08-13 10:39:02

有小伙伴表示微人事(https://github.com/lenve/vhr)的權(quán)限粒度不夠細(xì)。不過(guò)松哥想說(shuō)的是,技術(shù)都是相通的,明白了 vhr 中權(quán)限管理的原理,在此基礎(chǔ)上就可以去細(xì)化權(quán)限管理粒度,細(xì)化過(guò)程和還是用的 vhr 中用的技術(shù),只不過(guò)設(shè)計(jì)層面重新規(guī)劃而已。

當(dāng)然今天我想說(shuō)的并不是這個(gè)話(huà)題,主要是想和大家聊一聊 Spring Security 中權(quán)限管理粒度細(xì)化的問(wèn)題。因?yàn)檫@個(gè)問(wèn)題會(huì)涉及到不同的權(quán)限管理模型,今天和小伙伴們聊一聊~

1.權(quán)限管理模型

要想將細(xì)化權(quán)限粒度,我們不可避免會(huì)涉及到一些權(quán)限模型,例如 ACL、RBAC、DAC、MAC 以及 ABAC、PBAC 等。

在這些眾多的權(quán)限模型中,我們使用較多的是 RBAC,ACL 也有一些項(xiàng)目在使用,另外幾種則使用相對(duì)較少。因此松哥這里重點(diǎn)和大家介紹 ACL 和 RBAC。

1.1 ACL

ACL 是一種比較古老的權(quán)限控制模型。英文全稱(chēng)是 Access Control List,中文稱(chēng)作訪(fǎng)問(wèn)控制列表,這是一種面向資源的訪(fǎng)問(wèn)控制模型,所有的權(quán)限配置都是針對(duì)資源的。

它的原理是這樣:

對(duì)于系統(tǒng)中的每一個(gè)資源,都會(huì)配置一個(gè)訪(fǎng)問(wèn)列表,這個(gè)列表中記錄了用戶(hù)/角色對(duì)于資源的 CURD 權(quán)限,當(dāng)系統(tǒng)需要訪(fǎng)問(wèn)這些資源時(shí),會(huì)首先檢查列表中是否存在當(dāng)前用戶(hù)的訪(fǎng)問(wèn)權(quán)限,進(jìn)而確定當(dāng)前用戶(hù)是否可以執(zhí)行相應(yīng)的操作。

ACL 的使用非常簡(jiǎn)單,搞明白它的原理自己分分鐘就能實(shí)現(xiàn)。但是 ACL 有一個(gè)明顯的缺點(diǎn),就是需要維護(hù)大量的訪(fǎng)問(wèn)權(quán)限列表。大量的訪(fǎng)問(wèn)控制列表帶來(lái)的問(wèn)題就是性能下降以及維護(hù)復(fù)雜。

1.2 RBAC

RBAC(Role-based access control)是一種以角色為基礎(chǔ)的訪(fǎng)問(wèn)控制,也是目前使用較多的一種權(quán)限模型,它有多種不同的變體,松哥后面會(huì)專(zhuān)門(mén)寫(xiě)一篇文章來(lái)介紹 RBAC,這里僅簡(jiǎn)單科普下。

RBAC 權(quán)限模型將用戶(hù)按角色進(jìn)行歸類(lèi),通過(guò)用戶(hù)的角色來(lái)確定用戶(hù)對(duì)某項(xiàng)資源是否具備操作權(quán)限。RBAC 簡(jiǎn)化了用戶(hù)與權(quán)限的管理,它將用戶(hù)與角色關(guān)聯(lián)、角色與權(quán)限管理、權(quán)限與資源關(guān)聯(lián),這種模式使得用戶(hù)的授權(quán)管理變得非常簡(jiǎn)單和易于維護(hù)。

1.3 其他

下面這些使用常見(jiàn)較少,小伙伴們做一個(gè)了解即可,感興趣的小伙伴也可以自行研究下。

ABAC:這是一種基于屬性的訪(fǎng)問(wèn)控制。 PBAC:這是一種基于策略的訪(fǎng)問(wèn)控制。 DAC:除了權(quán)限控制,主體也可以將權(quán)限授予其他主體。 MAC:資源可以被哪些類(lèi)別的主體進(jìn)行哪些操作,主體可以對(duì)哪些等級(jí)的資源進(jìn)行哪些操作,這兩個(gè)條件同時(shí)滿(mǎn)足時(shí),允許訪(fǎng)問(wèn)。

2.ACL

接下來(lái)松哥要和大家仔細(xì)介紹一下 ACL 這種權(quán)限模型,RBAC 我后面專(zhuān)門(mén)寫(xiě)文章介紹,本文先不做討論。

Acl 的全稱(chēng)是 Access Control List,也就是我們所說(shuō)的訪(fǎng)問(wèn)控制列表,是用以控制對(duì)象的訪(fǎng)問(wèn)權(quán)限的。Acl 的一個(gè)核心思路就是將某個(gè)對(duì)象的某種權(quán)限授予某個(gè)用戶(hù)或某種角色,它們之間的關(guān)系是多對(duì)多,即一個(gè)用戶(hù)/角色可以具備某個(gè)對(duì)象的多種權(quán)限,某個(gè)對(duì)象的權(quán)限也可以被多個(gè)用戶(hù)/角色所持有。

舉個(gè)簡(jiǎn)單例子:

現(xiàn)在有一個(gè) User 對(duì)象,針對(duì)該對(duì)象有查詢(xún)、修改、刪除等權(quán)限,可以將這些權(quán)限賦值給某一個(gè)用戶(hù),也可以將這些權(quán)限賦值給某一個(gè)角色,當(dāng)用戶(hù)具備這些角色時(shí)就具有執(zhí)行相應(yīng)操作的權(quán)限。

從這個(gè)角度看,Acl 是一種粒度非常細(xì)的權(quán)限控制,它就是專(zhuān)門(mén)控制某一個(gè)對(duì)象的操作權(quán)限。所有的這些權(quán)限都記錄在數(shù)據(jù)庫(kù)中,這帶來(lái)了另外一個(gè)問(wèn)題就是需要維護(hù)的權(quán)限數(shù)據(jù)量非常龐大,不利于后期擴(kuò)展。當(dāng)然,對(duì)于一個(gè)簡(jiǎn)單的系統(tǒng),使用 Acl 還是可以的,沒(méi)有任何問(wèn)題。

2.1 核心概念

接下來(lái)我們來(lái)看看 Acl 中一些核心概念。

Sid

Sid 代表了用戶(hù)和角色,它有兩種:GrantedAuthoritySid 和 PrincipalSid,前者代表角色,后者代表用戶(hù)。在 Spring Security 中,用戶(hù)和角色信息都是保存在 Authentication 對(duì)象中的,即 Sid 是從 Authentication 對(duì)象中提取出來(lái)的,提取出來(lái)的值是 GrantedAuthoritySid+PrincipalSid,而不是其中某一項(xiàng),具體的提取方法是 SidRetrievalStrategyImpl#getSids,相關(guān)源碼如下:

public List<Sid> getSids(Authentication authentication) {Collection<? extends GrantedAuthority> authorities = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());List<Sid> sids = new ArrayList<>(authorities.size() + 1);sids.add(new PrincipalSid(authentication));for (GrantedAuthority authority : authorities) {sids.add(new GrantedAuthoritySid(authority));}return sids;}

這個(gè) Sid 大家可以簡(jiǎn)單理解為當(dāng)前用戶(hù)的權(quán)限(這個(gè)說(shuō)法不是很準(zhǔn)確,可以近似理解)。

ObjectIdentity

ObjectIdentity 是一個(gè)域?qū)ο螅@是官方的說(shuō)法,有點(diǎn)拗口。實(shí)際上這就是你要操作的對(duì)象。

例如我有一個(gè) User 對(duì)象,如果直接去記錄能夠?qū)?User 對(duì)象執(zhí)行哪些操作,這就會(huì)導(dǎo)致高耦和。所以我們需要對(duì)其解耦,將所有需要操作的對(duì)象通過(guò) ObjectIdentity 描述出來(lái),這樣就能確保權(quán)限系統(tǒng)不和具體的業(yè)務(wù)綁定。

ObjectIdentity 中有兩個(gè)關(guān)鍵方法,getType 和 getIdentifier。一般來(lái)說(shuō),getType 方法返回真實(shí)對(duì)象類(lèi)的全路徑,例如 org.javaboy.acl.model.User,getIdentifier 方法則返回真實(shí)對(duì)象的 id,通過(guò)這兩個(gè)方法,就能夠鎖定一個(gè)對(duì)象。

Acl

看名字就知道,這算是整個(gè)系統(tǒng)的核心調(diào)度部分。

一個(gè) Acl 對(duì)象會(huì)關(guān)聯(lián)一個(gè) ObjectIdentity,一個(gè) Acl 對(duì)象還擁有一個(gè) Sid,這個(gè) Sid 表示這個(gè) Acl 是屬于誰(shuí)的?屬于誰(shuí),誰(shuí)就可以修改甚至刪除這個(gè) Acl 對(duì)象。

AccessControlEntry

AccessControlEntry 簡(jiǎn)寫(xiě)為 ACE,一個(gè) AccessControlEntry 對(duì)象代表一條權(quán)限記錄。每一個(gè) AccessControlEntry 都對(duì)應(yīng)了一個(gè) Acl,一個(gè) Acl 對(duì)象對(duì)應(yīng)多個(gè) AccessControlEntry,有了這層對(duì)應(yīng)關(guān)系,相當(dāng)于就知道這個(gè)權(quán)限操作的是哪個(gè)對(duì)象。

然后 AccessControlEntry 中還包含一個(gè) Sid 和一個(gè) Permission 對(duì)象,表示某個(gè) Sid 具備某種權(quán)限。

可以看到,Acl+ACE,就描述出來(lái)了某個(gè) Sid 可以具備某個(gè) ObjectIdentity 的某種 Permission。

Permission

這個(gè)就是具體的權(quán)限對(duì)象。似乎是受 Linux 影響,它使用了權(quán)限掩碼,最多支持 232-1 種權(quán)限。

Spring Security 種默認(rèn)定義了五種

public class BasePermission extends AbstractPermission {public static final Permission READ = new BasePermission(1 << 0, ’R’); // 1public static final Permission WRITE = new BasePermission(1 << 1, ’W’); // 2public static final Permission CREATE = new BasePermission(1 << 2, ’C’); // 4public static final Permission DELETE = new BasePermission(1 << 3, ’D’); // 8public static final Permission ADMINISTRATION = new BasePermission(1 << 4, ’A’); // 16protected BasePermission(int mask) {super(mask);}protected BasePermission(int mask, char code) {super(mask, code);}}

 AclService

AclService 接口中主要定義了一些解析 Acl 對(duì)象的方法,通過(guò) ObjectIdentity 對(duì)象解析出其對(duì)應(yīng)的 Acl。

AclService 主要有兩類(lèi)實(shí)現(xiàn)接口:

JdbcAclService JdbcMutableAclService

前者主要是針對(duì) Acl 的查詢(xún)操作,后者支持 Acl 的添加、更新以及刪除等操作。我們常用的是 JdbcMutableAclService。

至此,Acl 中一些核心概念就和小伙伴們介紹完了。

2.2 Acl 數(shù)據(jù)表

上面提到的對(duì)象數(shù)據(jù),都需要對(duì)應(yīng)的數(shù)據(jù)表來(lái)維護(hù),在 spring-security-acl 依賴(lài)中,為這些數(shù)據(jù)表都提供了腳本。

Spring Security 中細(xì)化權(quán)限粒度的方法

可以看到,針對(duì)不同類(lèi)型的數(shù)據(jù)庫(kù),都有對(duì)應(yīng)的腳本。

這里主要涉及到四張表,接下來(lái)松哥以 MySQL 腳本為例,來(lái)分別介紹每張表的作用及其字段的含義。

acl_class

acl_class 是用來(lái)保存對(duì)象類(lèi)型的全路徑,如下:

Spring Security 中細(xì)化權(quán)限粒度的方法

這里的 id 自增長(zhǎng),class 中保存的是相應(yīng)對(duì)象的全路徑名。

acl_sid

acl_sid 表用來(lái)保存 Sid 的。

Spring Security 中細(xì)化權(quán)限粒度的方法

根據(jù)前面的介紹,存在兩種類(lèi)型的 Sid,GrantedAuthoritySid 和 PrincipalSid。所以這里的 principal 字段表示該 Sid 是哪種類(lèi)型的。

acl_object_identity

acl_object_identity 用來(lái)保存需要進(jìn)行訪(fǎng)問(wèn)控制的對(duì)象信息。

Spring Security 中細(xì)化權(quán)限粒度的方法

object_id_class:關(guān)聯(lián) acl_class.id。 object_id_identity:需要控制的對(duì)象的 id。 parent_object:父對(duì)象 ID,關(guān)聯(lián)一條 acl_object_identity 記錄。 owner_sid:這個(gè) acl 記錄擁有者的 sid。 entries_inheriting:是否需要繼承父對(duì)象的權(quán)限。

簡(jiǎn)單來(lái)說(shuō),這個(gè)表中的 object_id_class 和 object_id_identity 字段鎖定了你要進(jìn)行權(quán)限控制的對(duì)象,具體如何控制呢?則要看 acl_entry 中的關(guān)聯(lián)關(guān)系了。

acl_entry

這個(gè)表單純看數(shù)據(jù),一堆數(shù)字。

Spring Security 中細(xì)化權(quán)限粒度的方法

松哥來(lái)捋一下,大家就懂了。

acl_object_identity:關(guān)聯(lián) acl_object_identity.id。 ace_order:權(quán)限順序。 acl_object_identity 和 ace_order 的組合要唯一。 sid:關(guān)聯(lián) acl_sid.id。 這條權(quán)限記錄關(guān)聯(lián)哪個(gè)用戶(hù)/角色。 mask:權(quán)限掩碼。 granting:表示當(dāng)前記錄是否生效。 audit_success/audit_failure:審計(jì)信息。

簡(jiǎn)單來(lái)說(shuō),acl_entry 中的一條記錄,關(guān)聯(lián)了一個(gè)要操作的對(duì)象(acl_object_identity 和 ace_order 字段),關(guān)聯(lián)了 Sid(sid 字段),也描述了權(quán)限(mask),將權(quán)限涉及到的東西都在該字段中整合起來(lái)了。

3.小結(jié)

好啦,這就本文和小伙伴們科普一下 ACL 的概念,下篇文章松哥通過(guò)一個(gè)完整的案例來(lái)和小伙伴們演示具體用法~

參考資料:

https://blog.gaoyuexiang.cn/2020/07/02/spring-security-acl-conception-and-component

https://www.iteye.com/blog/elim-2269021

到此這篇關(guān)于Spring Security 中細(xì)化權(quán)限粒度的方法的文章就介紹到這了,更多相關(guān)Spring Security 細(xì)化權(quán)限粒度內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 霸州市| 安庆市| 济南市| 辰溪县| 商水县| 贵阳市| 安吉县| 兴隆县| 平原县| 海口市| 滦平县| 南充市| 辛集市| 明星| 普兰县| 台东市| 宁陵县| 万盛区| 项城市| 兴城市| 乐昌市| 遂平县| 延津县| 南开区| 阜康市| 广德县| 商洛市| 二连浩特市| 义乌市| 托里县| 镇坪县| 涿鹿县| 南涧| 崇左市| 宿松县| 栖霞市| 平舆县| 双城市| 互助| 墨脱县| 炎陵县|