第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

1. 前言

相比 Web 請求的安全及方法調(diào)用級別的安全,有些應(yīng)用還會定義更加復(fù)雜的訪問權(quán)限。在這種情況下,權(quán)限策略需要同時包含:

  • who」通過認(rèn)證(Authentication)完成;
  • where」在什么地方應(yīng)用;
  • what」安全對象是什么。

也就是說,權(quán)限策略除了考慮調(diào)用的方法,還有考慮調(diào)用域?qū)ο蟮膶?shí)例。

舉例說明。假設(shè)我們設(shè)計(jì)一個寵物診所的管理系統(tǒng),該系統(tǒng)有兩個主要用戶組:工作人員和客戶。員工可以訪問所有動物數(shù)據(jù),而客戶只能查看自己的數(shù)據(jù)。假設(shè)我們?yōu)樵撓到y(tǒng)擴(kuò)展了新的功能,即客戶可以授權(quán)其他用戶查看自己的數(shù)據(jù),比如其他寵物醫(yī)院的關(guān)聯(lián)機(jī)構(gòu),寵物俱樂部等等。在 Spring Security 項(xiàng)目中,我們有幾種實(shí)現(xiàn)方法:

  • 在業(yè)務(wù)方法中實(shí)現(xiàn)安全策略。

    比如,我們可以在「客戶」的域?qū)ο髮?shí)例中放置集合,通過權(quán)限的配置內(nèi)容,判斷集合中哪個用戶擁有訪問權(quán)限。這種方式下,我們使用 SecurityContextHolder.getContext().getAuthentication() 方式獲取權(quán)限對象。

  • 自定義訪問決策實(shí)例 AccessDecisionVoter 并配和 GrantedAuthority 對象。

    擴(kuò)展實(shí)現(xiàn) AccessDecisionVoter ,通過 Authentication 對象中 GrantedAuthority[] 集合的內(nèi)容實(shí)現(xiàn)安全策略。這種方式下,我們需要在權(quán)限對象 GrantedAuthority 體現(xiàn)出該主體是否有對其他「客戶」的訪問權(quán)限。

  • 自定義訪問決策實(shí)例 AccessDecisionVoter 直接通過「客戶」域?qū)ο髮?shí)例判定「客戶」權(quán)限。

    這種情況下 AccessDecisionVoter 對象需要有檢索「客戶」的數(shù)據(jù)訪問接口。

上述的方法都是適用的。但是,第一種方式中,授權(quán)檢查的代碼將會和業(yè)務(wù)代碼緊密關(guān)聯(lián),耦合度高,不便于單元測試。適用 GrantedAuthority 的方式的缺點(diǎn)是需要對每一個「客戶」實(shí)例進(jìn)行權(quán)限判斷,當(dāng)「客戶」數(shù)量很大時,這種做法執(zhí)行效率會降低。第三種做法相當(dāng)于直接從外部獲取「客戶」的全部信息,相對前兩種效果更好一些,即實(shí)現(xiàn)了代碼分離,又降低了內(nèi)存和計(jì)算量的消耗但是「客戶」對象被暴露了多次,第一次在權(quán)限判定時,第二次在業(yè)務(wù)邏輯時,這樣同樣降低了效率。同時,這三種方式都需要我們從頭開始編碼,所以這些方式都不是最佳方式。

Spring Security 為我們提供了一種便捷的域?qū)ο蟀踩芾聿呗裕竟?jié)主要討論域?qū)ο蟮臋?quán)限策略。

Spring Security 的域?qū)ο蟀踩珜?shí)現(xiàn)是通過 「ACLs(access control list)服務(wù)」方式實(shí)現(xiàn)。使用 Spring Security ACLs 服務(wù),需要導(dǎo)入 spring-security-acl-xxx.jar 依賴包。

Spring Security 域?qū)ο蟀踩δ芤?ACL 的概念為核心,系統(tǒng)中每一個域?qū)ο髮?shí)例都擁有各自的 ACL 配置表,該 ACL 記錄著該域訪問者的黑白名單列表。Spring Security 的 ACL 有三個主要操作:

  • 查詢和修改所有域?qū)ο蟮?ACL 配置
  • 在方法調(diào)用前,確保其主體參數(shù)可以被進(jìn)行權(quán)限判定;
  • 在方法調(diào)用后,確保其主體返回可以被進(jìn)行權(quán)限判斷。

這種方法的優(yōu)勢在于 ACL 的存儲和檢索的高效性。系統(tǒng)中域?qū)ο蟮拿總€實(shí)例都可能被多次訪問,ACL 提供了高性能的查詢能力、可插拔、最小化死鎖的數(shù)據(jù)庫修改操作、代碼獨(dú)立及完整的封裝。

圖片描述

2.1 ACL 的存儲

以數(shù)據(jù)庫方式為例,使用數(shù)據(jù)庫作為 ACL 存儲時,需要用到四個數(shù)據(jù)表:

  • ACL_SID

    系統(tǒng)中任何身份或者權(quán)限信息,都有一個 SID,即他的安全唯一標(biāo)識。該表包含列「ID」,文本類型,用于存儲 SID 值;和一個標(biāo)志列「Flag」,用來描述該 SID 是身份或是權(quán)限。因此,每一個身份或者權(quán)限都只有一條數(shù)據(jù),用來獲取授權(quán),SID 也被稱為「接收者(recipient)」

  • ACL_CLASS

    用于標(biāo)識域?qū)ο箢愋?。包含?ID 和域?qū)ο蟮?Java 類名。每一個域?qū)ο箢惷挥幸粭l ACL 記錄。

  • ACL_OBJECT_IDENTITY

    保存著系統(tǒng)里的所有域?qū)ο髮?shí)例,包含列「ID」、「ACL_CLASS.ID」、「ACL_SID.ID」。

  • ACL_ENTRY

    保存著獨(dú)立的許可記錄。包含外鍵「ACL_OBJECT_IDENTITY.ID」,標(biāo)識列表示是否允許或者拒絕,標(biāo)識的格式是二進(jìn)制的位掩碼形式。

ACL_ENTRY 中的掩碼位標(biāo)志著是否允許被訪問。默認(rèn)情況下0位代表讀、1位代表寫、2位代表創(chuàng)建、3位代表刪除、4位代表執(zhí)行。

2.2 ACL 主要對象和接口

  • ACL。每個域?qū)ο蠖加星覂H有一個「ACL」對象,該對象保持了 AccessControlEntry 及「ACL」的所有者?!窤CL」不直接引用域?qū)ο?,而是引?ObjectIdentity,存儲在 ACL_OBJECT_IDENTITY 表中。
  • AccessControlEntry。「ACL」中包含多個 AccessControlEntry 對象,在框架中被簡寫成 ace。每個 ace 關(guān)聯(lián) Permission、SidACL 的實(shí)例。ace 可以標(biāo)記為許可,也可以標(biāo)記為不允許,被存儲在 ACL_ENTRY 表中。
  • Permission。權(quán)限表示一個特定的不可變的位掩碼,具有匹配權(quán)限和信息輸出的功能?;緳?quán)限策略(0 位~4 位)包含在 BasePermission 類中。
  • Sid?!窤CL」模塊需要用到用戶的身份信息和權(quán)限信息。這些信息通過 Sid (Security identity)定位。常見的身份信息 Sid 類如 PrincipalSidGrantedAuthoritySid。這些信息存儲在 ACL_SID 表中。
  • ObjectIdentity。每個域?qū)ο笤凇窤CL」模塊內(nèi)部用 ObjectIdentity 表示。默認(rèn)實(shí)現(xiàn)類為 ObjectIdentityImpl。
  • AclService。檢索適用于給定 ObjectIdentityAcl 實(shí)例。其實(shí)現(xiàn)類有 JDBCAclService 等,檢索操作委托給 LookupStrategy 完成。LookupStrategy 為檢索「ACL」信息提供了一種高度優(yōu)化的策略,使用批處理檢索的方式「BasicLookupStrategy」,并支持利用視圖、分級查詢及其他高性能方案的「non-ANSI SQL」方式實(shí)現(xiàn)。
  • MutableAclService。允許「ACL」被修改變動。該接口如果不是必須的。

注意:現(xiàn)有的 AclService 及其數(shù)據(jù)庫相關(guān)類,使用的都是 ANSI-SQL。

3. 代碼演示

Spring Security 官方提供了兩個實(shí)例,它們演示了ACL模塊。第一個是關(guān)于聯(lián)系人的演示,第二個是文檔管理系統(tǒng)(DMS)案例。

使用 Spring Security ACL 功能的第一步,是確定 ACL 數(shù)據(jù)的存儲位置。這里需要實(shí)例化 DataSource,并將其注入到 JdbcMutableAclServiceBasicLookupStrategy 實(shí)例中。前者提供了修改的接口,后者用于提高「ACL」檢索效能。

當(dāng)上述內(nèi)容完成實(shí)例化之后,接下來我們需要確保域模型和 Spring Security ACL 的連通性。多數(shù)情況下域?qū)ο蠖及?public Serializable getId() 方法,用來返回域?qū)ο蟮奈ㄒ粯?biāo)識。

關(guān)于如何創(chuàng)建「ACL」或者修改現(xiàn)有「ACL」請看以下代碼:

// 為 ACE 準(zhǔn)備基本數(shù)據(jù)
ObjectIdentity oi = new ObjectIdentityImpl(Foo.class, new Long(44));
Sid sid = new PrincipalSid("Samantha");
Permission p = BasePermission.ADMINISTRATION;

// 創(chuàng)建 ACL 對象
MutableAcl acl = null;
try {
acl = (MutableAcl) aclService.readAclById(oi);
} catch (NotFoundException nfe) {
acl = aclService.createAcl(oi);
}

// 通過 ACE 授予更多權(quán)限
acl.insertAce(acl.getEntries().length, p, sid, true);
aclService.updateAcl(acl);

該實(shí)例中,演示了如何檢索標(biāo)識符為 44 的類型為 Foo 的域?qū)ο?。而后我們?chuàng)造了「ACE」,是名為「Samantha」的主體可以訪問和管理該對象。實(shí)例中 insertAce 方法的作用是插入條目,其最后一個 bool 值即為「允許」或「拒絕」,通常情況下,我們使用白名單「ACL」方式。

完成了上述內(nèi)容后,我們需要在數(shù)據(jù)庫中維護(hù)好「ACL」信息,并將「ACL」信息作為授權(quán)決策邏輯的一部分來使用。

一旦您使用了上述技術(shù)在數(shù)據(jù)庫中存儲一些ACL信息,下一步就是實(shí)際使用ACL信息作為授權(quán)決策邏輯的一部分。這一步實(shí)現(xiàn)方式有很多,比如擴(kuò)展 AccessDecisionInvestor 或者 AfterInvocationProvider,可以分別在方法執(zhí)行前后觸發(fā)鑒權(quán)。這些方法使用 AclService 檢索「ACL」,然后調(diào)用 Acl.isGranted(Permission[] permission, Sid[] sids, boolean administrativeMode) 決定是允許還是拒絕。同樣也可以使用 AclEntryVoter,AclEntryAfterInvocationProvider,AclEntryAfterInvocationCollectionFilteringProvider 類,所有這些類都提供了基于聲明的方式去獲取 ACL 信息,所以不需要我們每次修改權(quán)限代碼。

4. 小結(jié)

本節(jié)討論了域?qū)ο蟮陌踩渲貌呗裕饕獌?nèi)容有:

  • Spring Security 通過 ACL 方式實(shí)現(xiàn)高性能域?qū)ο蟮臋?quán)限控制;
  • Spring Security ACL 鑒權(quán)有基于關(guān)系型數(shù)據(jù)庫的成熟解決方案;
  • Spring Security ACL 模塊降低了執(zhí)行效率,也降低了開發(fā)工作量。

至此,關(guān)于權(quán)限部分的討論告一段落,從下節(jié)開始,我們討論 Spring Security 除了「認(rèn)證」和「鑒權(quán)」之外的常用操作。