成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

Spring Boot 集成Shiro的多realm實(shí)現(xiàn)以及shiro基本入門教程

瀏覽:101日期:2023-08-07 14:57:11

情景

我的項(xiàng)目中有六個(gè)用戶角色(學(xué)校管理員,學(xué)生等),需要進(jìn)行分別登陸。如果在一個(gè)realm中,對(duì)controller封裝好的Token進(jìn)行Service驗(yàn)證,需要在此realm中注入六個(gè)數(shù)據(jù)庫操作對(duì)象,然后寫一堆if語句來判斷應(yīng)該使用那個(gè)Service服務(wù),然后再在驗(yàn)證方法(doGetAuthorizationInfo)中寫一堆if來進(jìn)行分別授權(quán),這樣寫不僅會(huì)讓代碼可讀性會(huì)非常低而且很難后期維護(hù)修改(剛寫完的時(shí)候只有上帝和你能看懂你寫的是什么,一個(gè)月之后你寫的是什么就只有上帝能看懂了)。所以一定要配置多個(gè)realm來分別進(jìn)行認(rèn)證授權(quán)操作。shiro有對(duì)多個(gè)realm的處理,當(dāng)配置了多個(gè)Realm時(shí),shiro會(huì)用自帶的org.apache.shiro.authc.pam.ModularRealmAuthenticator類的doAuthenticate方法來進(jìn)行realm判斷,源碼:

protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException { assertRealmsConfigured(); Collection<Realm> realms = getRealms(); if (realms.size() == 1) { return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken); } else { return doMultiRealmAuthentication(realms, authenticationToken); } }

assertRealmsConfigured();的作用是驗(yàn)證realm列表是否為空,如果一個(gè)realm也沒有則會(huì)拋出IllegalStateException異常(爆紅:Configuration error: No realms have been configured! One or more realms must be present to execute an authentication attempt.)當(dāng)realm只有一個(gè)時(shí)直接返回,當(dāng)realm有多個(gè)時(shí)返回所有的realm。而我們要做的就是寫多個(gè)realm后重寫ModularRealmAuthenticator下的doAuthenticate方法,使它能滿足我們的項(xiàng)目需求。那么改怎么重寫ModularRealmAuthenticator下的doAuthenticate方法,使它能滿足我們的項(xiàng)目需求呢?這就需要分析我們使用shiro的使用方法了。

shiro的使用

1.Controller層中,獲取當(dāng)前用戶后將用戶名和密碼封裝UsernamePasswordToken對(duì)象,然后調(diào)用Subject中的登陸方法subject.login(UsernamePasswordToken)

@RequestMapping('/user/login')@ResponseBody public String Login(String userName,String password){ //獲取當(dāng)前用戶 subject Subject subject = SecurityUtils.getSubject(); //封裝用戶的登陸數(shù)據(jù) UsernamePasswordToken token = new UsernamePasswordToken(userName, password); try{ subject.login(token);//執(zhí)行登陸方法 return '登陸成功'; }catch (UnknownAccountException e){//用戶名不存在 model.addAttribute('msg','用戶名不存在'); return '用戶名不存在'; }catch (IncorrectCredentialsException e){//密碼錯(cuò)誤 model.addAttribute('msg','密碼錯(cuò)誤'); return '密碼錯(cuò)誤'; } }

(為了測試方便,我用了@ResponseBody返回字符串)2.完善自定義Realm類,繼承于AuthorizingRealm,主要實(shí)現(xiàn)doGetAuthorizationInfo和doGetAuthenticationInfo方法(需要實(shí)現(xiàn)認(rèn)證和授權(quán)方法,在這里方便測試主要是認(rèn)證)

public class StudentRealm extends AuthorizingRealm { @Resource private StudentsService studentsService; //授權(quán) @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } //認(rèn)證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println('Shiro=========Student認(rèn)證'); UserToken userToken = (UserToken) token; Students students = studentsService.queryByNum(userToken.getUsername()); //賬號(hào)不存在 if (students == null) { System.out.println('學(xué)生不存在'); //向上層提交UnknownAccountException異常,在controller層處理 throw new UnknownAccountException(); } //密碼認(rèn)證,shiro來做,可以自定義加密方式 return new SimpleAuthenticationInfo('', students.getPassword(), USER_LOGIN_TYPE); }}

3.配置shiro,將realm配置進(jìn)shiro(很多教程是使用xml配置或者ini配置,在這里用java代碼配置,功能都是一樣的,看個(gè)人習(xí)慣了)

@Configurationpublic class ShiroConfig { @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier('securityManager') DefaultWebSecurityManager defaultWebSecurityManager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //設(shè)置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); return bean; } //DefaultWebSecurityManager 默認(rèn)web安全管理器 @Bean(name = 'securityManager') public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier('userRealm') UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //關(guān)聯(lián)realm securityManager.setRealm(userRealm); return securityManager; } //創(chuàng)建自定義 realm @Bean public UserRealm userRealm() { return new UserRealm(); }}

記得加@Configuration注解!!!!!!!

經(jīng)過以上三步,可以看出shiro的簡略工作流程(非常簡略)就是,在web 啟動(dòng)階段,讀取@Configuration注解將自定義的ream配置進(jìn)默認(rèn)web安全管理器(DefaultWebSecurityManager)然后將DefaultWebSecurityManager與ShiroFilterFactoryBean相關(guān)聯(lián)。當(dāng)用戶登陸時(shí),從前端拿到username和password,封裝好Token后,進(jìn)入realm進(jìn)行認(rèn)證和授權(quán),而realm就來自于剛才的shiro的DefaultWebSecurityManager配置

多realm實(shí)現(xiàn)原理

根據(jù)上面的shiro簡略流程可知,shiro配置中寫入多個(gè)realm后,在controller提交token時(shí),只要多攜帶一個(gè)參數(shù),用來進(jìn)行org.apache.shiro.authc.pam.ModularRealmAuthenticator類的doAuthenticate(重寫后)的驗(yàn)證即可明確應(yīng)該用那個(gè)realm。那么,我們需要重寫org.apache.shiro.authc.UsernamePasswordToken(令其攜帶身份參數(shù)用于選擇realm)和org.apache.shiro.authc.pam.ModularRealmAuthenticator(令其根據(jù)token中的身份參數(shù)來進(jìn)行選擇realm)即可。

多realm實(shí)現(xiàn)具體操作

1.寫多個(gè)自定義的realm

public class AdminRealm extends AuthorizingRealm { @Resource private AdminService adminService; private static final String USER_LOGIN_TYPE = UserType.AdminRealm; @Override public String getName() { return UserType.AdminRealm; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println('Shiro=========Admin認(rèn)證'); UserToken userToken = (UserToken) token; Admin admin = adminService.queryById(userToken.getUsername()); if(admin == null){ System.out.println('管理員不存在'); throw new UnknownAccountException(); } return new SimpleAuthenticationInfo('', admin.getAdminpassword(), USER_LOGIN_TYPE); }}

2.創(chuàng)建靜態(tài)變量類(用于realm選擇)

public class UserType { //實(shí)習(xí)學(xué)校管理員 public static final String SchoolAdminRealm = 'schooladminrealm'; //學(xué)生 public static final String StudentRealm ='studentrealm'; //管理員 public static final String AdminRealm ='adminrealm_1'; //導(dǎo)員 public static final String InstructorRealm ='instructorrealm'; //實(shí)習(xí)帶隊(duì)老師 public static final String UniversityteacherRealm ='universityteacherrealm'; //實(shí)習(xí)指導(dǎo)老師 public static final String SchoolTeacherRealm ='schoolteacherrealm';}

3.重寫UsernamePasswordToken,令其可以攜帶身份參數(shù)

@Componentpublic class UserModularRealmAuthenticator extends ModularRealmAuthenticator { @Override protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) { // 判斷getRealms()是否返回為空,ModularRealmAuthenticator 自帶 assertRealmsConfigured(); // 強(qiáng)制轉(zhuǎn)換回自定義的UserToken UserToken token = (UserToken) authenticationToken; String loginType = token.getLoginType(); Collection<Realm> realms = getRealms(); for (Realm realm : realms) {System.out.println(realm.getName().toLowerCase()); if (realm.getName().toLowerCase().contains(loginType)){ //找到登錄類型對(duì)應(yīng)的指定Realmreturn doSingleRealmAuthentication(realm, token); } } //沒找到正確的realm的異常處理 String msg = 'Configuration error: Didn’t find the right realm'; throw new IllegalStateException(msg); }}

4.shiro的配置中寫入自定義的realm,還有其它配置

@Configurationpublic class ShiroConfig { @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier('securityManager') DefaultWebSecurityManager defaultWebSecurityManager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //設(shè)置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); return bean; } //DefaultWebSecurityManager @Bean(name = 'securityManager') public DefaultWebSecurityManager getDefaultWebSecurityManager( @Qualifier('schoolAdminRealm') SchoolAdminRealm schoolAdminRealm, @Qualifier('studentRealm') StudentRealm studentRealm, @Qualifier('adminRealm') AdminRealm adminRealm, @Qualifier('schoolTeacherRealm') SchoolTeacherRealm schoolTeacherRealm, @Qualifier('instructorRealm') InstructorRealm instructorRealm, @Qualifier('universityteacherRealm') UniversityteacherRealm universityteacherRealm, @Qualifier('userModularRealmAuthenticator') UserModularRealmAuthenticator userModularRealmAuthenticator ) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setAuthenticator(userModularRealmAuthenticator); /**關(guān)聯(lián)realm *securityManager.setRealm() 是配置單個(gè)realm,不可用它配置多個(gè)realm *securityManager.setRealms()配置多個(gè)realm, *List<Realm> realms可以直接被set進(jìn)去 */ List<Realm> realms = new ArrayList<Realm>(); realms.add(schoolAdminRealm); realms.add(studentRealm); realms.add(adminRealm); realms.add(schoolTeacherRealm); realms.add(instructorRealm); realms.add(universityteacherRealm); securityManager.setRealms(realms); System.out.println(securityManager.getRealms().toString()); return securityManager; } //實(shí)習(xí)學(xué)校管理員 @Bean(name = 'schoolAdminRealm') public SchoolAdminRealm SchoolAdminRealm() { return new SchoolAdminRealm(); } //學(xué)生 @Bean(name = 'studentRealm') public StudentRealm StudentRealm() { return new StudentRealm(); } //管理員 @Bean(name = 'adminRealm') public AdminRealm AdminRealm() { return new AdminRealm(); } //導(dǎo)員 @Bean(name = 'instructorRealm') public InstructorRealm InstructorRealm() { return new InstructorRealm(); } //實(shí)習(xí)帶隊(duì)老師 @Bean(name = 'universityteacherRealm') public UniversityteacherRealm UniversityteacherRealm() { return new UniversityteacherRealm(); } //實(shí)習(xí)指導(dǎo)老師 @Bean(name = 'schoolTeacherRealm') public SchoolTeacherRealm SchoolTeacherRealm() { return new SchoolTeacherRealm(); }}

5.在controller中使用重寫后的UsernamePasswordToken(UserToken)即可

//管理員登陸 @RequestMapping(value = '/AdminLogin', produces = 'text/html;charset=UTF-8') @ResponseBody//為了測試方便,返回字符串 public String AdminLogin( @RequestParam(value = 'username') String username, @RequestParam(value = 'password') String password) { //獲取當(dāng)前用戶 subject Subject subject = SecurityUtils.getSubject(); //封裝用戶的登陸數(shù)據(jù) UserToken token = new UserToken(username, Md5.getMd5(password), USER_LOGIN_TYPE); try { System.out.println('AdminLogin'); subject.login(token);//執(zhí)行登陸方法 return null; } catch (UnknownAccountException e) {//用戶名不存在 System.out.println('用戶名錯(cuò)誤'); return null; } catch (IncorrectCredentialsException e) {//密碼錯(cuò)誤 System.out.println('密碼錯(cuò)誤'); return null; }

參考文章

到此這篇關(guān)于Spring Boot 集成Shiro的多realm實(shí)現(xiàn)以及shiro基本入門的文章就介紹到這了,更多相關(guān)Spring Boot 集成Shiro內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
欧美日韩免费观看一区二区三区| 国产伦精品一区二区三区在线观看| 国产最新精品免费| 亚洲欧洲一区| 亚洲视频你懂的| 激情偷拍久久| 中文字幕在线观看一区| 欧美欧美全黄| 亚洲欧洲精品成人久久奇米网| 欧美精品一区二区三区在线看午夜| 精品成人私密视频| 99精品在线观看视频| 欧美精品一区二区在线观看| jlzzjlzz亚洲女人18| 欧美成人精品1314www| 九色|91porny| 欧美无砖砖区免费| 另类小说色综合网站| 91国模大尺度私拍在线视频 | 人人狠狠综合久久亚洲| 老妇喷水一区二区三区| 奇米777欧美一区二区| 欧美日韩午夜精品| 丰满少妇久久久久久久| 国产亚洲欧美一级| 狠狠入ady亚洲精品经典电影| 亚洲日本一区二区三区| 午夜亚洲激情| 久热成人在线视频| 欧美一级高清片| 97精品久久久午夜一区二区三区 | 欧美午夜宅男影院| 激情久久五月天| 日韩亚洲欧美一区| 欧美成熟视频| 亚洲另类中文字| 91黄色在线观看| 国产尤物一区二区在线| 久久亚洲影视婷婷| 亚洲国产一区二区三区高清| 亚洲a一区二区| 欧美精品久久天天躁| av综合在线播放| 亚洲女同一区二区| 在线免费一区三区| 成人av在线网站| 国产精品黄色在线观看| 亚洲欧美日韩精品在线| 韩国精品主播一区二区在线观看 | 免费观看日韩av| 欧美不卡一区二区三区| 在线 亚洲欧美在线综合一区| 亚洲成人自拍偷拍| 91精品国产一区二区三区| 亚洲欧美亚洲| 午夜天堂影视香蕉久久| 欧美电影一区二区| 欧美激情一区| 亚洲bt欧美bt精品| 日韩一级黄色大片| 国产一区二区在线观看免费播放| 亚洲亚洲精品在线观看| 在线播放日韩导航| 黑人巨大精品欧美一区二区小视频 | 欧美性天天影院| 亚洲在线观看免费视频| 88在线观看91蜜桃国自产| 91免费国产在线观看| 五月婷婷激情综合网| 日韩欧美久久久| 亚洲精品乱码视频| 国产精品综合一区二区三区| 国产精品素人视频| 色婷婷综合久久久| 99久久er热在这里只有精品66| 夜色激情一区二区| 日韩一区二区影院| 在线视频精品| 成人午夜视频免费看| 亚洲愉拍自拍另类高清精品| 91麻豆精品国产91久久久久| 亚洲电影专区| 国产剧情一区二区三区| 欧美性生活久久| 午夜精品亚洲| 免费高清在线一区| 国产精品国产自产拍在线| 欧美日韩国产乱码电影| 在线成人www免费观看视频| 精品一区二区av| 亚洲视频一区在线观看| 欧美一区二区人人喊爽| 一区二区三区久久网| 成人免费高清在线观看| 亚洲电影你懂得| 久久精品亚洲精品国产欧美 | 国产精品久线在线观看| 欧美性大战久久久久久久蜜臀| 午夜日韩激情| 久久精品99国产精品日本| 亚洲欧美电影在线观看| 成人免费看黄yyy456| 日本欧美大码aⅴ在线播放| 亚洲国产精品av| 制服丝袜成人动漫| 午夜在线播放视频欧美| 99国产欧美久久久精品| 免费成人在线网站| 亚洲人成网站色在线观看| 欧美tk—视频vk| 欧美性大战久久久| 国内一区二区在线视频观看| 国产一区二区三区综合 | 99久久精品国产导航| 蜜臀久久99精品久久久久宅男 | 亚洲国产精品成人久久综合一区| 欧美三级日韩三级国产三级| 亚洲精美视频| 97久久精品人人做人人爽| 国产一区免费电影| 偷窥少妇高潮呻吟av久久免费| 国产精品污污网站在线观看| 欧美一级精品大片| 一本大道av一区二区在线播放| 一区二区在线不卡| 成人91在线观看| 韩国理伦片一区二区三区在线播放| 亚洲国产中文字幕在线视频综合| 日本一区二区不卡视频| 日韩美一区二区三区| 欧美私模裸体表演在线观看| 日韩视频中文| 99久久久久久| 国产一区二区三区四| 性久久久久久久久| 亚洲三级小视频| 国产精品美日韩| 久久亚洲精品国产精品紫薇| 欧美日韩激情一区| 色天天综合久久久久综合片| 国产乱人伦精品一区二区| 在线观看一区视频| 欧美日韩精品免费观看视一区二区| 成人午夜av影视| 国产在线精品一区二区不卡了| 午夜电影一区二区三区| 一二三四区精品视频| 中文字幕一区视频| 国产性色一区二区| 久久综合九色综合欧美98| 日韩一级成人av| 欧美日韩国产高清一区| 欧洲一区二区av| 午夜一区在线| 国产一区二区久久久| 亚洲裸体俱乐部裸体舞表演av| 精品不卡一区| 国模一区二区三区| 欧美欧美全黄| 国产综合18久久久久久| 亚洲一区影音先锋| 亚洲精品视频免费观看| 最新日韩在线视频| 亚洲四区在线观看| 亚洲人精品一区| 亚洲乱码国产乱码精品精小说| 亚洲欧洲一区二区三区| 国产精品国产自产拍高清av王其| 国产欧美日韩在线视频| 久久久久99精品国产片| 国产日本欧洲亚洲| 中文一区二区在线观看| 中文字幕一区视频| 亚洲精品久久嫩草网站秘色| 亚洲精品欧美综合四区| 亚洲免费观看高清完整| 亚洲自拍偷拍网站| 亚洲第一激情av| 视频一区二区欧美| 麻豆精品新av中文字幕| 国产乱码精品一区二区三区忘忧草| 国产一二精品视频| 日韩欧美一区在线| 日韩精品最新网址| 久久蜜臀精品av| 国产精品福利av| 一二三区精品视频| 日本伊人色综合网| 激情偷乱视频一区二区三区| 国产精品一区二区久久不卡| 国产suv精品一区二区6| 91免费版在线看| 狠狠色综合一区二区| 国产精品久久久久久久免费软件| 羞羞视频在线观看欧美| 欧美午夜片在线观看| 欧美一区2区视频在线观看| 精品国产乱码久久久久久久| 久久久亚洲欧洲日产国码αv| 国产精品久久777777|