SpringSecurity的角色繼承分析

這篇文章主要介紹“SpringSecurity的角色繼承分析”,在日常操作中,相信很多人在SpringSecurity的角色繼承分析問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”SpringSecurity的角色繼承分析”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

十余年的迎江網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整迎江建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“迎江網(wǎng)站設(shè)計(jì)”,“迎江網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

今天想和小伙伴們來(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è)話題和最新版 Spring Boot 的還是有一點(diǎn)差別。

以前的寫(xiě)法

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

@BeanRoleHierarchy 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 角色才能訪問(wèn)的資源, ROLE_dba 和 ROLE_admin 也都能訪問(wèn),具備 ROLE_amdin 角色才能訪問(wèn)的資源, ROLE_dba 也能訪問(wèn)。

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

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

@BeanRoleHierarchy 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)系即可,如下:

@Overrideprotected 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 角色才能訪問(wèn), /admin/** 格式的路徑則需要具備 admin 角色才能訪問(wèn), /user/** 格式的路徑,則需要具備 user 角色才能訪問(wèn),此時(shí)提供相關(guān)接口,會(huì)發(fā)現(xiàn),dba 除了訪問(wèn) /db/** ,也能訪問(wèn) /admin/** 和 /user/** ,admin 角色除了訪問(wèn) /admin/** ,也能訪問(wèn) /user/** ,user 角色則只能訪問(wèn) /user/** 。

源碼分析

這樣兩種不同的寫(xiě)法,其實(shí)也對(duì)應(yīng)了兩種不同的解析策略,角色繼承關(guān)系的解析在 RoleHierarchyImpl 類的 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ě)法。

到此,關(guān)于“SpringSecurity的角色繼承分析”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

當(dāng)前題目:SpringSecurity的角色繼承分析
標(biāo)題來(lái)源:http://www.muchs.cn/article2/ijcgic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)移動(dòng)網(wǎng)站建設(shè)、云服務(wù)器、定制網(wǎng)站軟件開(kāi)發(fā)、標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)