SpringBoot整合Shiro實(shí)現(xiàn)權(quán)限控制的代碼實(shí)現(xiàn)_第1頁
SpringBoot整合Shiro實(shí)現(xiàn)權(quán)限控制的代碼實(shí)現(xiàn)_第2頁
SpringBoot整合Shiro實(shí)現(xiàn)權(quán)限控制的代碼實(shí)現(xiàn)_第3頁
SpringBoot整合Shiro實(shí)現(xiàn)權(quán)限控制的代碼實(shí)現(xiàn)_第4頁
SpringBoot整合Shiro實(shí)現(xiàn)權(quán)限控制的代碼實(shí)現(xiàn)_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第SpringBoot整合Shiro實(shí)現(xiàn)權(quán)限控制的代碼實(shí)現(xiàn)1、SpringBoot整合Shiro

ApacheShiro是一個(gè)強(qiáng)大且易用的Java安全框架,執(zhí)行身份驗(yàn)證、授權(quán)、密碼和會(huì)話管理。

1.1、shiro簡(jiǎn)介

shiro有個(gè)核心組件,分別為Subject、SecurityManager和Realms

Subject:相當(dāng)于當(dāng)前操作的”用戶“,這個(gè)用戶不一定是一個(gè)具體的人,是一個(gè)抽象的概念,表明的是和當(dāng)前程序進(jìn)行交互的任何東西,例如爬蟲、腳本、等等。所有的Subject都綁定到SecurityManager上,與Subject的所有交互都會(huì)委托給SecurityManager;可以把Subject認(rèn)為是一個(gè)門面;SecurityManager才是實(shí)際的執(zhí)行者。

SecurityManager:這個(gè)是shiro框架的核心,所有與安全相關(guān)的操作都會(huì)與它進(jìn)行交互,它管理者所有的Subject。

Realms:充當(dāng)了Shiro與應(yīng)用安全數(shù)據(jù)間的”橋梁“,當(dāng)對(duì)用戶執(zhí)行認(rèn)證(登錄)和授權(quán)(訪問控制)驗(yàn)證時(shí),SecurityManager需要從Realm獲取相應(yīng)的用戶進(jìn)行比較以確定用戶身份是否合法;也需要從Realm得到用戶相應(yīng)的角色/權(quán)限進(jìn)行驗(yàn)證用戶是否能進(jìn)行操作。

如果想要更加深入的了解的shrio可以參考:/shiro/co4m1if2.html

1.2、代碼的具體實(shí)現(xiàn)

1.2.1、Maven的配置

!--shiro--

dependency

groupIdorg.apache.shiro/groupId

artifactIdshiro-spring-boot-starter/artifactId

version1.7.1/version

/dependency

!--shiro整合thymeleaf--

dependency

groupIdcom.github.theborakompanioni/groupId

artifactIdthymeleaf-extras-shiro/artifactId

version2.0.0/version

/dependency

!--shiro緩存--

dependency

groupIdorg.apache.shiro/groupId

artifactIdshiro-ehcache/artifactId

version1.7.1/version

/dependency

shiro默認(rèn)是與jsp進(jìn)行使用的,而這里是shiro整合thymeleaf所有要導(dǎo)入shiro整合thymeleaf的jar包

1.2.2、整合需要實(shí)現(xiàn)的類

一般來說整合只需要完成兩個(gè)類的實(shí)現(xiàn)即可

一個(gè)是ShiroConfig一個(gè)是CustomerRealm

如果需要添加shiro緩存并且不是自帶的緩存而是redis緩存還需要進(jìn)行另外兩個(gè)類的編寫

一個(gè)是RedisCache一個(gè)是RedisCacheManager

1.2.3、項(xiàng)目結(jié)構(gòu)

1.2.4、ShiroConfig的實(shí)現(xiàn)

未加shiro的緩存

packagecom.yuwen.config;

importat.pollux.thymeleaf.shiro.dialect.ShiroDialect;

importcom.yuwen.shiro.cache.RedisCacheManager;

importcom.yuwen.shiro.realm.CustomerRealm;

importorg.apache.shiro.authc.credential.HashedCredentialsMatcher;

importorg.apache.shiro.realm.Realm;

importorg.apache.shiro.spring.web.ShiroFilterFactoryBean;

importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;

importorg.springframework.beans.factory.annotation.Qualifier;

importorg.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

importjava.util.HashMap;

importjava.util.Map;

@Configuration

publicclassShiroConfig{

//讓頁面shiro標(biāo)簽生效

@Bean

publicShiroDialectshiroDialect(){

returnnewShiroDialect();

//1、創(chuàng)建shiroFilter負(fù)責(zé)攔截所有請(qǐng)求

@Bean

publicShiroFilterFactoryBeanshiroFilterFactoryBean(DefaultWebSecurityManagerdefaultWebSecurityManager){

ShiroFilterFactoryBeanfactoryBean=newShiroFilterFactoryBean();

//給filter設(shè)置安全管理

factoryBean.setSecurityManager(defaultWebSecurityManager);

//配置系統(tǒng)的受限資源

//配置系統(tǒng)公共資源全部都能訪問的設(shè)置anon

MapString,Stringmap=newHashMap();

map.put("/main","authc");//請(qǐng)求這個(gè)資源需要認(rèn)證和授權(quán)authc表示需要認(rèn)證后才能訪問

map.put("/admin","roles[admin]");//表示admin角色才能訪問roles[]表示需要什么角色才能訪問

map.put("/manage","perms[user:*:*]");//表示需要user:*:*權(quán)限才能訪問perms[]表示需要什么權(quán)限才能訪問

//訪問需要認(rèn)證的頁面如果未登錄會(huì)跳轉(zhuǎn)到/login路由進(jìn)行登陸

factoryBean.setLoginUrl("/login");

//訪問未授權(quán)頁面會(huì)自動(dòng)跳轉(zhuǎn)到/unAuth路由

factoryBean.setUnauthorizedUrl("/unAuth");

factoryBean.setFilterChainDefinitionMap(map);

returnfactoryBean;

//2、創(chuàng)建安全管理器

@Bean

publicDefaultWebSecurityManagerdefaultWebSecurityManager(@Qualifier("getRealm")Realmrealm){

DefaultWebSecurityManagersecurityManager=newDefaultWebSecurityManager();

//給安全管理器設(shè)置

securityManager.setRealm(realm);

returnsecurityManager;

//3、創(chuàng)建自定義的realm

@Bean

publicRealmgetRealm(){

CustomerRealmcustomerRealm=newCustomerRealm();

//修改憑證校驗(yàn)匹配器

HashedCredentialsMatchercredentialsMatcher=newHashedCredentialsMatcher();

//設(shè)置加密算法為md5

credentialsMatcher.setHashAlgorithmName("MD5");

//設(shè)置散列次數(shù)

credentialsMatcher.setHashIterations(1024);

customerRealm.setCredentialsMatcher(credentialsMatcher);

returncustomerRealm;

}

因?yàn)橐话阍跀?shù)據(jù)庫中設(shè)置明文密碼不安全,所有我這里對(duì)密碼進(jìn)行了md5加密,我的加密方式為:密碼=密碼+鹽+散列次數(shù)而后進(jìn)行MD5加密所以這里創(chuàng)建自定義的realm時(shí)需要進(jìn)行設(shè)置匹配器這樣登錄時(shí)密碼才能匹配成功

1.2.5、CustomerRealm的實(shí)現(xiàn)

packagecom.yuwen.shiro.realm;

importcom.yuwen.pojo.User;

importcom.yuwen.pojo.vo.ViewPerms;

importcom.yuwen.pojo.vo.ViewRole;

importcom.yuwen.service.UserService;

importcom.yuwen.shiro.salt.MyByteSource;

importorg.apache.shiro.authc.AuthenticationException;

importorg.apache.shiro.authc.AuthenticationInfo;

importorg.apache.shiro.authc.AuthenticationToken;

importorg.apache.shiro.authc.SimpleAuthenticationInfo;

importorg.apache.shiro.authz.AuthorizationInfo;

importorg.apache.shiro.authz.SimpleAuthorizationInfo;

importorg.apache.shiro.realm.AuthorizingRealm;

importorg.apache.shiro.subject.PrincipalCollection;

importorg.apache.shiro.util.CollectionUtils;

importorg.springframework.util.ObjectUtils;

importjavax.annotation.Resource;

importjava.util.List;

//自定義realm

publicclassCustomerRealmextendsAuthorizingRealm{

@Resource

privateUserServiceuserService;

//授權(quán)

@Override

protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipalCollection){

//獲取身份信息

StringprimaryPrincipal=(String)principalCollection.getPrimaryPrincipal();

//根據(jù)主身份信息獲取角色和權(quán)限信息

ListViewRoleroles=userService.findRolesByUsername(primaryPrincipal);

if(!CollectionUtils.isEmpty(roles)){

SimpleAuthorizationInfosimpleAuthorizationInfo=newSimpleAuthorizationInfo();

roles.forEach(viewRole-{

simpleAuthorizationInfo.addRole(viewRole.getName());

//權(quán)限信息

ListViewPermsperms=userService.findPermsByRoleId(viewRole.getName());

if(!CollectionUtils.isEmpty(perms)){

perms.forEach(viewPerms-{

simpleAuthorizationInfo.addStringPermission(viewPerms.getPName());

returnsimpleAuthorizationInfo;

returnnull;

//認(rèn)證

@Override

protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthenticationToken)throwsAuthenticationException{

//獲取登入的身份信息

Stringprincipal=(String)authenticationToken.getPrincipal();

Useruser=userService.findByUsername(principal);

if(!ObjectUtils.isEmpty(user)){

//ByteSource.Util.bytes(user.getSalt())通過這個(gè)工具將鹽傳入

//如果身份認(rèn)證驗(yàn)證成功,返回一個(gè)AuthenticationInfo實(shí)現(xiàn);

returnnewSimpleAuthenticationInfo(user.getUsername(),user.getPassword(),newMyByteSource(user.getSalt()),this.getName());

returnnull;

}

在登錄時(shí)會(huì)自動(dòng)調(diào)用這個(gè)身份驗(yàn)證在驗(yàn)證時(shí)如果出錯(cuò),會(huì)報(bào)異常,我在controller層接收了異常并處理

controller層中登錄時(shí)的異常處理

@PostMapping("/login")

publicStringlogin(Stringusername,Stringpassword){

//獲取主體對(duì)象

Subjectsubject=SecurityUtils.getSubject();

try{

//自動(dòng)調(diào)用CustomerRealm類中的身份驗(yàn)證方法

subject.login(newUsernamePasswordToken(username,password));

return"index";

}catch(UnknownAccountExceptione){//接收異常并處理

e.printStackTrace();

model.addAttribute("msg","用戶名有誤,請(qǐng)重新登錄");

}catch(IncorrectCredentialsExceptione){//接收異常并處理

e.printStackTrace();

model.addAttribute("msg","密碼有誤,請(qǐng)重新登錄");

return"login";

}

1.2.6、shiro緩存配置

定義了shiro緩存,用戶登錄后,其用戶信息、擁有的角色/權(quán)限不必每次去查,這樣可以提高效率

默認(rèn)緩存的配置

在ShiroConfig中的getRealm()方法中開啟緩存管理

@Bean

publicRealmgetRealm(){

CustomerRealmcustomerRealm=newCustomerRealm();

//開啟緩存管理

customerRealm.setCacheManager(newEhCacheManager());

//開啟全局緩存

customerRealm.setCachingEnabled(true);

//開啟認(rèn)證緩存

customerRealm.setAuthenticationCachingEnabled(true);

customerRealm.setAuthenticationCacheName("authenticationCache");

//開啟權(quán)限緩存

customerRealm.setAuthorizationCachingEnabled(true);

customerRealm.setAuthorizationCacheName("authorizationCache");

returncustomerRealm;

}

與reids整合的緩存這里就不說明了,放在源碼里自己查看,源碼在下方

1.2.7、主頁index.html的設(shè)置

在這里用標(biāo)簽來判斷某些區(qū)域需要認(rèn)證或什么角色或者什么權(quán)限才能訪問

!DOCTYPEhtml

htmllang="en"xmlns="/1999

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論