




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年寧波余姚市婦幼保健院醫(yī)共體第一次招聘編外人員18人考前自測(cè)高頻考點(diǎn)模擬試題帶答案詳解
- 2025-2026學(xué)年湖北省部分高中高一上學(xué)期開學(xué)分班考試英語試題(解析版)
- 推動(dòng)科技創(chuàng)新投入承諾書6篇
- 2025年鶴壁市山城區(qū)城市管理局招聘看護(hù)人員30人模擬試卷及完整答案詳解一套
- 2025湖南省衛(wèi)生健康委直屬事業(yè)單位高層次人才公開招聘218人考前自測(cè)高頻考點(diǎn)模擬試題參考答案詳解
- 我的精彩演講稿分享7篇
- 研究生錄取協(xié)議書7篇
- 2025年金華義烏市中心醫(yī)院招聘護(hù)理全日制本科崗位10人模擬試卷附答案詳解
- 2025年煙臺(tái)萊陽市衛(wèi)生健康局所屬事業(yè)單位公開招聘工作人員(35人)考前自測(cè)高頻考點(diǎn)模擬試題附答案詳解
- 2025湖南湘能多經(jīng)產(chǎn)業(yè)(集團(tuán))有限公司高校畢業(yè)生招聘(第三批)模擬試卷及答案詳解(名校卷)
- 治療性作業(yè)活動(dòng)-游戲類作業(yè)活動(dòng)(作業(yè)治療技術(shù)課件)
- 江蘇理文化工有限公司年產(chǎn)30萬噸聚氯乙烯、5萬噸氯化聚氯乙烯裝置及配套工程項(xiàng)目環(huán)評(píng)報(bào)告
- 腹腔鏡下右側(cè)輸卵管切除術(shù) 左側(cè)輸卵管結(jié)扎術(shù)手術(shù)記錄
- 農(nóng)民田間學(xué)校
- 各類應(yīng)急演練方案腳本大全
- 高速磁浮大跨度橋梁設(shè)計(jì)關(guān)鍵技術(shù)介紹
- 紅藍(lán)簡(jiǎn)明萬人計(jì)劃青年拔尖人才答辯PPT模板
- DB23T 2550-2020 政務(wù)服務(wù)大廳建設(shè)和管理規(guī)范
- 生態(tài)系統(tǒng)服務(wù)功能與生態(tài)保護(hù)
- 基于PLC的物料分揀系統(tǒng)設(shè)計(jì)論文
- 《教育統(tǒng)計(jì)與測(cè)量》筆記(一).
評(píng)論
0/150
提交評(píng)論