成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringSecurity原理剖析與權(quán)限系統(tǒng)設(shè)計(jì)

安全
Spring Secutity和Apache Shiro是Java領(lǐng)域的兩大主流開源安全框架,也是權(quán)限系統(tǒng)設(shè)計(jì)的主要技術(shù)選型。本文主要介紹Spring Secutity的實(shí)現(xiàn)原理,并基于Spring Secutity設(shè)計(jì)基于RBAC的權(quán)限系統(tǒng)。

 Spring Secutity和Apache Shiro是Java領(lǐng)域的兩大主流開源安全框架,也是權(quán)限系統(tǒng)設(shè)計(jì)的主要技術(shù)選型。本文主要介紹Spring Secutity的實(shí)現(xiàn)原理,并基于Spring Secutity設(shè)計(jì)基于RBAC的權(quán)限系統(tǒng)。

[[284792]]

一、技術(shù)選型

  1. 為何把Spring Secutity作為權(quán)限系統(tǒng)的技術(shù)選型,主要考慮了以下幾個(gè)方面:
  2. 數(shù)據(jù)鑒權(quán)的能力:Spring Secutity支持?jǐn)?shù)據(jù)鑒權(quán),即細(xì)粒度權(quán)限控制。
  3. Spring生態(tài)基礎(chǔ):Spring Secutity可以和Spring生態(tài)無縫集成。

多樣認(rèn)證能力:Spring Secutity支持多樣認(rèn)證方式,如預(yù)認(rèn)證方式可以與第三方認(rèn)證系統(tǒng)集成。

 

SpringSecurity原理剖析與權(quán)限系統(tǒng)設(shè)計(jì)

 

二、核心架構(gòu)

權(quán)限系統(tǒng)一般包含兩大核心模塊:認(rèn)證(Authentication)和鑒權(quán)(Authorization)。

  • 認(rèn)證:認(rèn)證模塊負(fù)責(zé)驗(yàn)證用戶身份的合法性,生成認(rèn)證令牌,并保存到服務(wù)端會(huì)話中(如TLS)。
  • 鑒權(quán):鑒權(quán)模塊負(fù)責(zé)從服務(wù)端會(huì)話內(nèi)獲取用戶身份信息,與訪問的資源進(jìn)行權(quán)限比對。

官方給出的Spring Security的核心架構(gòu)圖如下:

 

SpringSecurity原理剖析與權(quán)限系統(tǒng)設(shè)計(jì)

 

核心架構(gòu)解讀:

  • AuthenticationManager:負(fù)責(zé)認(rèn)證管理,解析用戶登錄信息(封裝在Authentication),讀取用戶、角色、權(quán)限信息進(jìn)行認(rèn)證,認(rèn)證結(jié)果被回填到Authentication,保存在SecurityContext。
  • AccessDecisionManager:負(fù)責(zé)鑒權(quán)投票表決,匯總投票器的結(jié)果,實(shí)現(xiàn)一票通過(默認(rèn))、多票通過、一票否決策略。
  • SecurityInterceptor:負(fù)責(zé)權(quán)限攔截,包括Web URL攔截和方法調(diào)用攔截。通過ConfigAttributes獲取資源的描述信息,借助于AccessDecisionManager進(jìn)行鑒權(quán)攔截。
  • SecurityContext:安全上下文,保存認(rèn)證結(jié)果。提供了全局上下文、線程繼承上下文、線程獨(dú)立上下文(默認(rèn))三種策略。
  • Authentication:認(rèn)證信息,保存用戶的身份標(biāo)示、權(quán)限列表、證書、認(rèn)證通過標(biāo)記等信息。
  • SecuredResource:被安全管控的資源,如Web URL、用戶、角色、自定義領(lǐng)域?qū)ο蟮取?/li>
  • ConfigAttributes:資源屬性配置,描述安全管控資源的信息,為SecurityInterceptor提供攔截邏輯的輸入。

三、設(shè)計(jì)原理

通過對源碼的分析,我把Spring Security的核心領(lǐng)域模型設(shè)計(jì)整理如下:

 

SpringSecurity原理剖析與權(quán)限系統(tǒng)設(shè)計(jì)

 

全局抽象模型解讀:

  • 配置:AuthenticationConfiguration負(fù)責(zé)認(rèn)證系統(tǒng)的全局配置,GlobalMethodSecurityConfiguration負(fù)責(zé)方法調(diào)用攔截的全局配置。
  • 構(gòu)建:AuthenticationConfiguration通過AuthenticationManagerBuilder構(gòu)建認(rèn)證管理器AuthenticationManager,GlobalMethodSecurityConfiguration會(huì)自動(dòng)初始化AbstractSecurityInterceptor進(jìn)行方法調(diào)用攔截。
  • Web攔截:HttpSecurity對Web進(jìn)行安全配置,內(nèi)置了大量GenericFilterBean過濾器對URL進(jìn)行攔截。負(fù)責(zé)認(rèn)證的過濾器會(huì)通過AuthenticationManager進(jìn)行認(rèn)證,并將認(rèn)證結(jié)果保存到SecurityContext。
  • 方法攔截:Spring通過AOP技術(shù)(cglib/aspectj)對標(biāo)記為@PreAuthorize、@PreFilter、@PostAuthorize、@PostFilter等注解的方法進(jìn)行攔截,通過AbstractSecurityInterceptor調(diào)用AuthenticationManager進(jìn)行身份認(rèn)證(如果必要的話)。
  • 認(rèn)證:認(rèn)證管理器AuthenticationManager內(nèi)置了多種認(rèn)證器AuthenticationProvider,只要其中一個(gè)認(rèn)證通過,認(rèn)證便成功。不同的AuthenticationProvider獲取各自需要的信息(HTTP請求、數(shù)據(jù)庫查詢、遠(yuǎn)程服務(wù)等)進(jìn)行認(rèn)證,認(rèn)證結(jié)果全部封裝在Authentication。需要加載用戶、角色、權(quán)限信息的認(rèn)證器(如密碼認(rèn)證、預(yù)認(rèn)證等)需要對接UserDetailsManager接口實(shí)現(xiàn)用戶CRUD功能。
  • 鑒權(quán):權(quán)限攔截器AbstractSecurityInterceptor通過讀取不同的SecurityMetadataSource加載需要被鑒權(quán)資源的描述信息ConfigAttribute,然后把認(rèn)證信息Authentication、資源描述ConfigAttribute、資源對象本身傳遞給AccessDecisionManager進(jìn)行表決。AccessDecisionManager內(nèi)置了多個(gè)投票器AccessDecisionVoter,投票器會(huì)將鑒權(quán)信息中的ConfigAttribute轉(zhuǎn)換為SpringEL的格式,通過表達(dá)式處理器SecurityExpressionHandler執(zhí)行基于表達(dá)式的鑒權(quán)邏輯,鑒權(quán)邏輯會(huì)通過反射的方式轉(zhuǎn)發(fā)到SecurityExpressionRoot的各個(gè)操作上去。
  • 定制:通過WebSecurityConfigureAdapter可以定制HTTP安全配置HttpSecurity和認(rèn)證管理器生成器AuthenticationManagerBuilder;通過AbstractPreAuthenticatedProcessingFilter可以定制預(yù)認(rèn)證過濾器;通過UserDetailsManager和UserDetails接口可以對接自定義數(shù)據(jù)源;通過GrantedAuthority定制權(quán)限信息;通過PermissionEvaluator可以定制自定義領(lǐng)域模型的訪問控制邏輯。

四、應(yīng)用集成

理清Spring Security的定制點(diǎn)后,就可以在系統(tǒng)內(nèi)部集成Spring Security了。

這里使用預(yù)認(rèn)證的方式,以適配第三方認(rèn)證系統(tǒng)。AbstractPreAuthenticatedProcessingFilter提供了預(yù)認(rèn)證的擴(kuò)展點(diǎn),基于該抽象類實(shí)現(xiàn)一個(gè)自定義認(rèn)證過濾器。

  1. public class MyPreAuthFilter extends AbstractPreAuthenticatedProcessingFilter { 
  2.  @Override 
  3.  protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { 
  4.  // 從第三方系統(tǒng)獲取用戶ID 
  5.  return userId; 
  6.  } 
  7.  @Override 
  8.  protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { 
  9.  return ""
  10.  } 

Spring Security會(huì)根據(jù)預(yù)認(rèn)證過濾器getPreAuthenticatedPrincipal返回的用戶ID信息,加載用戶角色等初始信息。這里需要實(shí)現(xiàn)UserDetailsManager接口,提供用戶信息管理器。

  1. @Service 
  2. public class MyUserManager implements UserDetailsManager { 
  3.  @Override 
  4.  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
  5.  // 從數(shù)據(jù)庫加載用戶信息 
  6.  return user
  7.  } 
  8.   
  9.  // 其他管理接口 

UserDetails內(nèi)包含了GrantedAuthority接口類型的權(quán)限信息抽象,一般可以基于它自定義角色和權(quán)限。Spring Security使用一種接口形式表達(dá)角色和權(quán)限,角色和權(quán)限的差別是角色的ID是以"ROLE_"為前綴。

  1. public class MyRole implements GrantedAuthority { 
  2.  private final String role; 
  3.  @Override 
  4.  public String getAuthority() { 
  5.  return "ROLE_" + role; 
  6.  } 
  7. public class MyAuthority implements GrantedAuthority { 
  8.  private final String authority; 
  9.  @Override 
  10.  public String getAuthority() { 
  11.  return authority; 
  12.  } 

接下來注冊自定義認(rèn)證過濾器和用戶管理器,這里需要實(shí)現(xiàn)WebSecurityConfigurerAdapter進(jìn)行Web安全配置。

  1. @EnableWebSecurity 
  2. @EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.PROXY) 
  3. public class MySecurityConfig extends WebSecurityConfigurerAdapter { 
  4.  @Autowired 
  5.  UserDetailsManager userDetailsManager; 
  6.  @Bean 
  7.  protected AuthenticationProvider createPreAuthProvider() { 
  8.  // 注冊用戶管理器 
  9.  PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); 
  10.  provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsManager)); 
  11.  return provider; 
  12.  } 
  13.  @Override 
  14.  protected void configure(HttpSecurity http) throws Exception { 
  15.  // 注冊預(yù)認(rèn)證過濾器 
  16.  http.addFilter(new MyPreAuthFilter(authenticationManager())); 
  17.  } 

這樣,最簡單的Spring Security框架集成內(nèi)系統(tǒng)內(nèi)部已經(jīng)完成了。在系統(tǒng)的任意服務(wù)接口上可以使用如下方式進(jìn)行鑒權(quán)。

  1. public interface MyService { 
  2.  @PreAuthorize("hasAuthority('QUERY')"
  3.  Object getById(String id); 
  4.   
  5.  @PreAuthorize("hasRole('ADMIN')"
  6.  void deleteById(String id); 

PreAuthorize注解表示調(diào)用前鑒權(quán),Spring使用默認(rèn)使用動(dòng)態(tài)代理技術(shù)生成鑒權(quán)邏輯。注解內(nèi)配置了SpringEL表達(dá)式來定制鑒權(quán)方式。上述代碼中,hasAuthority會(huì)檢查用戶是否有QUERY權(quán)限,hasRole會(huì)檢查用戶是否有ADMIN角色。

使用動(dòng)態(tài)代理的方式進(jìn)行AOP,只允許在接口層面進(jìn)行權(quán)限攔截,如果想在任意的方法上進(jìn)行權(quán)限攔截,那么就需要借助于AspectJ的方式進(jìn)行AOP。首先將注解EnableGlobalMethodSecurity的mode設(shè)置為AdviceMode.ASPECTJ,然后添加JVM啟動(dòng)參數(shù),這樣就可以在任意方法上使用Spring Security的注解了。

  1. javaagent:/path/to/org/aspectj/aspectjweaver/1.9.4/aspectjweaver-1.9.4.jar 

以上還是只是以用戶的身份信息(角色/權(quán)限)進(jìn)行權(quán)限,靈活度有限,也發(fā)揮不了Spring Security的數(shù)據(jù)鑒權(quán)的能力。要使用數(shù)據(jù)鑒權(quán),需要實(shí)現(xiàn)一個(gè)Spring Bean。

  1. @Component 
  2. public class MyPermissionEvaluator implements PermissionEvaluator { 
  3.  @Override 
  4.  public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { 
  5.  // 自定義數(shù)據(jù)鑒權(quán) 
  6.  return false
  7.  } 
  8.  @Override 
  9.  public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) { 
  10.  // 自定義數(shù)據(jù)鑒權(quán) 
  11.  return false
  12.  } 

PermissionEvaluator會(huì)被自動(dòng)注冊到Spring Security框架,并允許在注解內(nèi)使用如下方式進(jìn)行鑒權(quán)。

  1. @PreAuthorize("hasPermission(#id, 'QUERY')"
  2. Object func1(String id) { 
  3. @PreAuthorize("hasPermission(#id, 'TABLE', 'QUERY')"
  4. Object func2(String id) { 

其中,func1的注解表示校驗(yàn)用戶是否對id有QUERY權(quán)限,代碼邏輯路由到MyPermissionEvaluator的第一個(gè)接口。func2的注解表示校驗(yàn)用戶是否對TABLE類型的id有QUERY權(quán)限,代碼邏輯路由到MyPermissionEvaluator的第二個(gè)接口。PermissionEvaluator提供了權(quán)限系統(tǒng)中數(shù)據(jù)鑒權(quán)的擴(kuò)展點(diǎn),稍后會(huì)描述如何利用該擴(kuò)展點(diǎn)定制基于RBAC的權(quán)限系統(tǒng)。

五、權(quán)限系統(tǒng)

構(gòu)建基于RBAC(Role Based Access Control)的權(quán)限系統(tǒng),需要明確用戶、角色、權(quán)限、資源這幾個(gè)核心的概念類的含義和它們之間的關(guān)系。

資源:權(quán)限系統(tǒng)內(nèi)需要安全控制的客體,一般是系統(tǒng)內(nèi)的數(shù)據(jù)或功能。

權(quán)限:描述了資源上的操作抽象,一般是一種動(dòng)作。

授權(quán):是權(quán)限和資源的組合,表示對資源的某一個(gè)操作。

角色:描述了一組授權(quán)的集合,表示一類特殊概念的功能集。

用戶:權(quán)限系統(tǒng)的主體,一般是當(dāng)前系統(tǒng)的訪問用戶,用戶可以擁有多種角色。

以下是我們設(shè)計(jì)的基于RABC的權(quán)限核心領(lǐng)域模型:

 

SpringSecurity原理剖析與權(quán)限系統(tǒng)設(shè)計(jì)

 

一般情況下,系統(tǒng)內(nèi)需要權(quán)限管控的資源是無法用戶自定義的,因?yàn)橘Y源會(huì)耦合大量的業(yè)務(wù)邏輯,所以我們提供了自 資源工廠,通過配置化的方式構(gòu)建業(yè)務(wù)模塊所需的資源。而用戶、角色、權(quán)限,以及授權(quán)記錄都是可以通過相應(yīng)的管理器進(jìn)行查詢更新。

另外,資源抽象允許表達(dá)資源的繼承和組合關(guān)系,繼而表達(dá)更復(fù)雜的資源模型,資源統(tǒng)一鑒權(quán)的流程為:

 

SpringSecurity原理剖析與權(quán)限系統(tǒng)設(shè)計(jì)

 

  • 執(zhí)行鑒權(quán)時(shí),首先看資源是原子資源還是組合資源。
  • 對于原子資源,先查詢是否有授權(quán)記錄,再查看角色預(yù)授權(quán)是否包含當(dāng)前授權(quán),存在一種便成功。
  • 沒有授權(quán)記錄和角色預(yù)授權(quán)的原子資源,嘗試用父資源(如果有的話)代替鑒權(quán),否則鑒權(quán)失敗。
  • 對于組合資源,先進(jìn)行資源展開,獲取子資源列表。
  • 遍歷子資源列表,并依次對子資源進(jìn)行鑒權(quán),子資源鑒權(quán)結(jié)果匯總后,即組合資源鑒權(quán)結(jié)果。
  • 綜上,基于統(tǒng)一資源抽象和資源配置化構(gòu)建,可以實(shí)現(xiàn)資源的統(tǒng)一構(gòu)建,繼而實(shí)現(xiàn)統(tǒng)一鑒權(quán)。

六、總結(jié)回顧

本文從Spring Security的架構(gòu)和原理出發(fā),描述了開源安全框架對于認(rèn)證和鑒權(quán)模塊的設(shè)計(jì)思路和細(xì)節(jié)。并提供了系統(tǒng)內(nèi)集成Spring Security的方法,結(jié)合RBAC通用權(quán)限系統(tǒng)模型,討論了統(tǒng)一資源構(gòu)建和統(tǒng)一鑒權(quán)的設(shè)計(jì)和實(shí)現(xiàn)。如果你也需要設(shè)計(jì)一個(gè)新的權(quán)限系統(tǒng),希望本文對你有所幫助。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2009-08-03 14:15:24

ASP.NET系統(tǒng)用戶

2022-06-30 10:00:28

數(shù)據(jù)系統(tǒng)

2023-04-06 13:15:48

MySQL復(fù)制原理應(yīng)用實(shí)踐

2016-12-19 14:35:32

Spark Strea原理剖析數(shù)據(jù)

2009-10-19 14:39:10

2017-10-26 12:26:45

云計(jì)算SaaS平臺(tái)管理

2025-02-24 08:00:00

線程池Java開發(fā)

2025-03-06 00:00:05

DPIHD開發(fā)

2025-02-12 00:29:58

2024-04-07 11:48:01

系統(tǒng)設(shè)計(jì)微服務(wù)

2016-11-25 20:52:14

Linux

2009-09-14 10:35:15

Linq內(nèi)部執(zhí)行原理

2020-09-16 10:31:58

SMTP網(wǎng)絡(luò)電子郵件

2022-07-18 08:39:18

ACL訪問控制機(jī)制

2025-04-15 02:25:00

2024-07-11 08:17:00

2009-11-23 15:24:40

2023-07-12 08:44:46

湖倉存儲(chǔ)系統(tǒng)數(shù)據(jù)湖

2009-03-05 10:04:42

NTFS系統(tǒng)安全權(quán)限

2021-11-11 10:48:35

架構(gòu)運(yùn)維技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日本又色又爽又黄又高潮 | 国产精品精品视频 | 黄色一级大片视频 | 黄色片a级 | 7777精品伊人久久精品影视 | 亚州午夜精品 | 国产精品美女久久久久久免费 | 日本成人在线播放 | 国产精品福利网站 | 中文字幕1区2区 | 日韩欧美在线观看 | 日日操av | 成人久久18免费网站图片 | 91极品尤物在线播放国产 | 亚洲一区二区三区视频在线 | 伊人超碰 | 毛片在线免费 | 亚洲一级毛片 | 日韩一区精品 | 久久机热 | 全免费a级毛片免费看视频免 | av在线一区二区三区 | 午夜在线精品 | 国产精品成人在线播放 | 国产精品高清在线 | 精品欧美乱码久久久久久 | 日韩精品一区二区三区视频播放 | 福利视频网站 | 一级黄色av电影 | 91精品国产综合久久婷婷香蕉 | 色花av| 国产免费一级一级 | 日本二区在线观看 | 午夜影院在线观看 | 久久久人| 日韩中文av在线 | 久久机热 | 韩国毛片一区二区三区 | 欧美精品91 | 最新国产精品精品视频 | 精品亚洲一区二区三区 |