最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Security角色繼承分析

 更新時(shí)間:2019年11月01日 09:52:44   作者:江南一點(diǎn)雨  
這篇文章主要介紹了Spring Security角色繼承分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

今天想和小伙伴們來(lái)聊一聊 Spring Security 中的角色繼承問(wèn)題。

角色繼承實(shí)際上是一個(gè)很常見(jiàn)的需求,因?yàn)榇蟛糠止局卫砜赡芏际墙鹱炙蔚?,上司可能具備下屬的部分甚至所有?quán)限,這一現(xiàn)實(shí)場(chǎng)景,反映到我們的代碼中,就是角色繼承了。

Spring Security 中為開(kāi)發(fā)者提供了相關(guān)的角色繼承解決方案,但是這一解決方案在最近的 Spring Security 版本變遷中,使用方法有所變化。今天除了和小伙伴們分享角色繼承外,也來(lái)順便說(shuō)說(shuō)這種變化,避免小伙伴們踩坑,同時(shí)購(gòu)買(mǎi)了我的書(shū)的小伙伴也需要留意,書(shū)是基于 Spring Boot2.0.4 這個(gè)版本寫(xiě)的,這個(gè)話(huà)題和最新版 Spring Boot 的還是有一點(diǎn)差別。

以前的寫(xiě)法

這里說(shuō)的以前寫(xiě)法,就是指 SpringBoot2.0.8(含)之前的寫(xiě)法,在之前的寫(xiě)法中,角色繼承只需要開(kāi)發(fā)者提供一個(gè) RoleHierarchy 接口的實(shí)例即可,例如下面這樣:

@Bean
RoleHierarchy roleHierarchy() {
  RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
  String hierarchy = "ROLE_dba > ROLE_admin ROLE_admin > ROLE_user";
  roleHierarchy.setHierarchy(hierarchy);
  return roleHierarchy;
}

在這里我們提供了一個(gè) RoleHierarchy 接口的實(shí)例,使用字符串來(lái)描述了角色之間的繼承關(guān)系, ROLE_dba 具備 ROLE_admin 的所有權(quán)限,而 ROLE_admin 則具備 ROLE_user 的所有權(quán)限,繼承與繼承之間用一個(gè)空格隔開(kāi)。提供了這個(gè) Bean 之后,以后所有具備 ROLE_user 角色才能訪(fǎng)問(wèn)的資源, ROLE_dba 和 ROLE_admin 也都能訪(fǎng)問(wèn),具備 ROLE_amdin 角色才能訪(fǎng)問(wèn)的資源, ROLE_dba 也能訪(fǎng)問(wèn)。

現(xiàn)在的寫(xiě)法

但是上面這種寫(xiě)法僅限于 Spring Boot2.0.8(含)之前的版本,在之后的版本中,這種寫(xiě)法則不被支持,新版的寫(xiě)法是下面這樣:

@Bean
RoleHierarchy roleHierarchy() {
  RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
  String hierarchy = "ROLE_dba > ROLE_admin \n ROLE_admin > ROLE_user";
  roleHierarchy.setHierarchy(hierarchy);
  return roleHierarchy;
}

變化主要就是分隔符,將原來(lái)用空格隔開(kāi)的地方,現(xiàn)在用換行符了。這里表達(dá)式的含義依然和上面一樣,不再贅述。

上面兩種不同寫(xiě)法都是配置角色的繼承關(guān)系,配置完成后,接下來(lái)指定角色和資源的對(duì)應(yīng)關(guān)系即可,如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
  http.authorizeRequests().antMatchers("/admin/**")
      .hasRole("admin")
      .antMatchers("/db/**")
      .hasRole("dba")
      .antMatchers("/user/**")
      .hasRole("user")
      .and()
      .formLogin()
      .loginProcessingUrl("/doLogin")
      .permitAll()
      .and()
      .csrf().disable();
}

這個(gè)表示 /db/** 格式的路徑需要具備 dba 角色才能訪(fǎng)問(wèn), /admin/** 格式的路徑則需要具備 admin 角色才能訪(fǎng)問(wèn), /user/** 格式的路徑,則需要具備 user 角色才能訪(fǎng)問(wèn),此時(shí)提供相關(guān)接口,會(huì)發(fā)現(xiàn),dba 除了訪(fǎng)問(wèn) /db/** ,也能訪(fǎng)問(wèn) /admin/** 和 /user/** ,admin 角色除了訪(fǎng)問(wèn) /admin/** ,也能訪(fǎng)問(wèn) /user/** ,user 角色則只能訪(fǎng)問(wèn) /user/** 。

源碼分析

這樣兩種不同的寫(xiě)法,其實(shí)也對(duì)應(yīng)了兩種不同的解析策略,角色繼承關(guān)系的解析在 RoleHierarchyImpl 類(lèi)的 buildRolesReachableInOneStepMap 方法中,Spring Boot2.0.8(含)之前該方法的源碼如下:

private void buildRolesReachableInOneStepMap() {
	Pattern pattern = Pattern.compile("(\\s*([^\\s>]+)\\s*>\\s*([^\\s>]+))");
	Matcher roleHierarchyMatcher = pattern
			.matcher(this.roleHierarchyStringRepresentation);
	this.rolesReachableInOneStepMap = new HashMap<GrantedAuthority, Set<GrantedAuthority>>();
	while (roleHierarchyMatcher.find()) {
		GrantedAuthority higherRole = new SimpleGrantedAuthority(
				roleHierarchyMatcher.group(2));
		GrantedAuthority lowerRole = new SimpleGrantedAuthority(
				roleHierarchyMatcher.group(3));
		Set<GrantedAuthority> rolesReachableInOneStepSet;
		if (!this.rolesReachableInOneStepMap.containsKey(higherRole)) {
			rolesReachableInOneStepSet = new HashSet<>();
			this.rolesReachableInOneStepMap.put(higherRole,
					rolesReachableInOneStepSet);
		}
		else {
			rolesReachableInOneStepSet = this.rolesReachableInOneStepMap
					.get(higherRole);
		}
		addReachableRoles(rolesReachableInOneStepSet, lowerRole);
		logger.debug("buildRolesReachableInOneStepMap() - From role " + higherRole
				+ " one can reach role " + lowerRole + " in one step.");
	}
}

從這段源碼中我們可以看到,角色的繼承關(guān)系是通過(guò)正則表達(dá)式進(jìn)行解析,通過(guò)空格進(jìn)行切分,然后構(gòu)建相應(yīng)的 map 出來(lái)。

Spring Boot2.1.0(含)之后該方法的源碼如下:

private void buildRolesReachableInOneStepMap() {
	this.rolesReachableInOneStepMap = new HashMap<GrantedAuthority, Set<GrantedAuthority>>();
	try (BufferedReader bufferedReader = new BufferedReader(
			new StringReader(this.roleHierarchyStringRepresentation))) {
		for (String readLine; (readLine = bufferedReader.readLine()) != null;) {
			String[] roles = readLine.split(" > ");
			for (int i = 1; i < roles.length; i++) {
				GrantedAuthority higherRole = new SimpleGrantedAuthority(
						roles[i - 1].replaceAll("^\\s+|\\s+$", ""));
				GrantedAuthority lowerRole = new SimpleGrantedAuthority(roles[i].replaceAll("^\\s+|\\s+$
				Set<GrantedAuthority> rolesReachableInOneStepSet;
				if (!this.rolesReachableInOneStepMap.containsKey(higherRole)) {
					rolesReachableInOneStepSet = new HashSet<GrantedAuthority>();
					this.rolesReachableInOneStepMap.put(higherRole, rolesReachableInOneStepSet);
				} else {
					rolesReachableInOneStepSet = this.rolesReachableInOneStepMap.get(higherRole);
				}
				addReachableRoles(rolesReachableInOneStepSet, lowerRole);
				if (logger.isDebugEnabled()) {
					logger.debug("buildRolesReachableInOneStepMap() - From role " + higherRole
							+ " one can reach role " + lowerRole + " in one step.");
				}
			}
		}
	} catch (IOException e) {
		throw new IllegalStateException(e);
	}
}

從這里我們可以看到,這里并沒(méi)有一上來(lái)就是用正則表達(dá)式,而是先將角色繼承字符串轉(zhuǎn)為一個(gè) BufferedReader ,然后一行一行的讀出來(lái),再進(jìn)行解析,最后再構(gòu)建相應(yīng)的 map。從這里我們可以看出為什么前后版本對(duì)此有不同的寫(xiě)法。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java設(shè)計(jì)模式中的原型模式講解

    Java設(shè)計(jì)模式中的原型模式講解

    原型模式是用于創(chuàng)建重復(fù)的對(duì)象,同時(shí)又能保證性能。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式,今天通過(guò)本文給大家介紹下Java?原型設(shè)計(jì)模式,感興趣的朋友一起看看吧
    2023-04-04
  • 淺談Maven環(huán)境隔離應(yīng)用

    淺談Maven環(huán)境隔離應(yīng)用

    這篇文章主要介紹了淺談Maven環(huán)境隔離應(yīng)用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • java多線(xiàn)程教程之如何使用線(xiàn)程池詳解

    java多線(xiàn)程教程之如何使用線(xiàn)程池詳解

    這篇文章主要給大家介紹了關(guān)于java多線(xiàn)程之如何使用線(xiàn)程池的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • java9區(qū)分opens與exports

    java9區(qū)分opens與exports

    本篇文章主要給大家講述了java9中opens與exports的區(qū)別以及用法的不同之處,一起學(xué)習(xí)下吧。
    2018-02-02
  • Java Runtime用法實(shí)戰(zhàn)案例

    Java Runtime用法實(shí)戰(zhàn)案例

    這篇文章主要介紹了Java Runtime用法,結(jié)合實(shí)例形式分析了Runtime針對(duì)系統(tǒng)內(nèi)存、處理器信息的獲取相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • 淺析Spring IOC bean為什么默認(rèn)是單例

    淺析Spring IOC bean為什么默認(rèn)是單例

    單例的意思就是說(shuō)在 Spring IoC 容器中只會(huì)存在一個(gè) bean 的實(shí)例,無(wú)論一次調(diào)用還是多次調(diào)用,始終指向的都是同一個(gè) bean 對(duì)象,本文小編將和大家一起分析Spring IOC bean為什么默認(rèn)是單例,需要的朋友可以參考下
    2023-12-12
  • Java項(xiàng)目中添加外部jar包的兩種方式(收藏版)

    Java項(xiàng)目中添加外部jar包的兩種方式(收藏版)

    這篇文章主要介紹了java項(xiàng)目中添加外部jar包的兩種方式,第二種方式是將外部jar包引入到本地maven倉(cāng)庫(kù)中,本文給大家講解的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • java實(shí)現(xiàn)人工智能化屏幕監(jiān)控窗口

    java實(shí)現(xiàn)人工智能化屏幕監(jiān)控窗口

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)人工智能化屏幕監(jiān)控窗口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • 在Java中將double轉(zhuǎn)換為int的操作方法

    在Java中將double轉(zhuǎn)換為int的操作方法

    這篇文章主要介紹了在Java中將double轉(zhuǎn)換為int的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Java Chassis3注冊(cè)中心分區(qū)隔離技術(shù)解密

    Java Chassis3注冊(cè)中心分區(qū)隔離技術(shù)解密

    這篇文章主要為大家介紹了Java Chassis3注冊(cè)中心分區(qū)隔離技術(shù)解密,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01

最新評(píng)論

遂昌县| 四平市| 东山县| 长治县| 于都县| 巴中市| 易门县| 民丰县| 三原县| 静宁县| 古浪县| 珲春市| 龙岩市| 双城市| 青龙| 英吉沙县| 襄汾县| 宽城| 甘孜县| 博兴县| 姚安县| 宁安市| 鄂温| 新蔡县| 台州市| 名山县| 台东县| 广饶县| 西和县| 南岸区| 永春县| 揭东县| 衡东县| 平远县| 鄂尔多斯市| 宜昌市| 通江县| 卓尼县| 聂拉木县| 寿阳县| 阿克|