日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

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

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

情景

我的項目中有六個用戶角色(學校管理員,學生等),需要進行分別登陸。如果在一個realm中,對controller封裝好的Token進行Service驗證,需要在此realm中注入六個數(shù)據(jù)庫操作對象,然后寫一堆if語句來判斷應該使用那個Service服務,然后再在驗證方法(doGetAuthorizationInfo)中寫一堆if來進行分別授權(quán),這樣寫不僅會讓代碼可讀性會非常低而且很難后期維護修改(剛寫完的時候只有上帝和你能看懂你寫的是什么,一個月之后你寫的是什么就只有上帝能看懂了)。所以一定要配置多個realm來分別進行認證授權(quán)操作。shiro有對多個realm的處理,當配置了多個Realm時,shiro會用自帶的org.apache.shiro.authc.pam.ModularRealmAuthenticator類的doAuthenticate方法來進行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();的作用是驗證realm列表是否為空,如果一個realm也沒有則會拋出IllegalStateException異常(爆紅:Configuration error: No realms have been configured! One or more realms must be present to execute an authentication attempt.)當realm只有一個時直接返回,當realm有多個時返回所有的realm。而我們要做的就是寫多個realm后重寫ModularRealmAuthenticator下的doAuthenticate方法,使它能滿足我們的項目需求。那么改怎么重寫ModularRealmAuthenticator下的doAuthenticate方法,使它能滿足我們的項目需求呢?這就需要分析我們使用shiro的使用方法了。

shiro的使用

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

@RequestMapping('/user/login')@ResponseBody public String Login(String userName,String password){ //獲取當前用戶 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){//密碼錯誤 model.addAttribute('msg','密碼錯誤'); return '密碼錯誤'; } }

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

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

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

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

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

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

多realm實現(xiàn)原理

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

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

1.寫多個自定義的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認證'); 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 { //實習學校管理員 public static final String SchoolAdminRealm = 'schooladminrealm'; //學生 public static final String StudentRealm ='studentrealm'; //管理員 public static final String AdminRealm ='adminrealm_1'; //導員 public static final String InstructorRealm ='instructorrealm'; //實習帶隊老師 public static final String UniversityteacherRealm ='universityteacherrealm'; //實習指導老師 public static final String SchoolTeacherRealm ='schoolteacherrealm';}

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

@Componentpublic class UserModularRealmAuthenticator extends ModularRealmAuthenticator { @Override protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) { // 判斷getRealms()是否返回為空,ModularRealmAuthenticator 自帶 assertRealmsConfigured(); // 強制轉(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)){ //找到登錄類型對應的指定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(); //設置安全管理器 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); /**關聯(lián)realm *securityManager.setRealm() 是配置單個realm,不可用它配置多個realm *securityManager.setRealms()配置多個realm, *List<Realm> realms可以直接被set進去 */ 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; } //實習學校管理員 @Bean(name = 'schoolAdminRealm') public SchoolAdminRealm SchoolAdminRealm() { return new SchoolAdminRealm(); } //學生 @Bean(name = 'studentRealm') public StudentRealm StudentRealm() { return new StudentRealm(); } //管理員 @Bean(name = 'adminRealm') public AdminRealm AdminRealm() { return new AdminRealm(); } //導員 @Bean(name = 'instructorRealm') public InstructorRealm InstructorRealm() { return new InstructorRealm(); } //實習帶隊老師 @Bean(name = 'universityteacherRealm') public UniversityteacherRealm UniversityteacherRealm() { return new UniversityteacherRealm(); } //實習指導老師 @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) { //獲取當前用戶 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('用戶名錯誤'); return null; } catch (IncorrectCredentialsException e) {//密碼錯誤 System.out.println('密碼錯誤'); return null; }

參考文章

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

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产极品一区| 久久人人99| 国产精品久久久久久久久久齐齐 | 悠悠资源网久久精品| 久久香蕉精品| 老牛影视精品| 日韩高清在线观看一区二区| 日韩精品网站| 国产极品一区| 日韩精品1区2区3区| 欧美精选一区二区三区| 欧美日韩视频一区二区三区| 国产三级一区| 亚洲欧美网站在线观看| 私拍精品福利视频在线一区| 国产精品男女| 奇米狠狠一区二区三区| 国产婷婷精品| 久久精品国产68国产精品亚洲| 精品国产三区在线| 蜜桃av在线播放| 久久久久国产精品一区三寸| 亚洲香蕉网站| 日韩一区精品| 欧美1区二区| 久久高清免费| 视频一区视频二区中文字幕| 日韩制服丝袜先锋影音| 日韩av午夜在线观看| 久久精品国产久精国产爱| 欧美www视频在线观看| 亚洲激情不卡| 国产日产精品一区二区三区四区的观看方式 | 成人亚洲一区二区| 亚洲手机视频| 日韩av中文字幕一区二区三区| 婷婷激情综合| 91精品91| 久久国产亚洲| 亚洲一区二区av| 国产精品亚洲成在人线| 亚洲午夜天堂| 日韩精品久久久久久久软件91| 久久精品二区亚洲w码| 亚洲综合不卡| 狠狠久久伊人| 日韩国产91| 性色一区二区| 国产一区二区三区国产精品| 亚洲欧美日韩国产| 亚洲精品日本| 精品捆绑调教一区二区三区| 成人羞羞视频播放网站| 在线日韩成人| 国产精品高清一区二区| 伊人久久亚洲影院| 99久久精品费精品国产| 中文字幕在线视频久| 久久九九99| 国产亚洲一卡2卡3卡4卡新区| 亚洲午夜av| 日韩欧美一区二区三区在线观看 | 日韩毛片视频| 国产日韩欧美一区在线| 蜜桃久久av一区| 狠狠久久婷婷| 欧美精品黄色| 99视频一区| 亚洲欧美久久精品| 精品三级在线观看视频| 国产伦一区二区三区| 狠狠操综合网| 久久精品资源| 精品国产乱码久久久久久1区2匹| 91欧美极品| 久久国产精品免费精品3p| 中文字幕一区二区三区四区久久| 91视频精品| 日本精品在线中文字幕| 欧美三区四区| 中文日韩在线| 亚洲精品视频一二三区| 日韩高清二区| 国产精品美女午夜爽爽| 麻豆一区二区三| 欧产日产国产精品视频| 日韩一区二区三区精品视频第3页| 在线亚洲激情| 日韩在线一二三区| 欧美a级一区二区| 国产欧美精品久久| 久久精品123| 国际精品欧美精品| 久久久久中文| 在线国产精品一区| 91精品国产自产观看在线| 高清av一区| 伊人久久亚洲| 激情黄产视频在线免费观看| 亚洲天堂久久| 国产精品调教| 尹人成人综合网| 麻豆精品在线播放| 午夜在线视频观看日韩17c| 美女久久久久久| 丝袜国产日韩另类美女| 亚洲中午字幕| 欧美日韩精品一区二区视频| 私拍精品福利视频在线一区| 综合激情一区| 国产欧美69| 国产一区日韩欧美| 国产精品chinese| 亚欧洲精品视频在线观看| 99视频精品视频高清免费| 国产乱码精品一区二区三区四区 | 精品成av人一区二区三区| 尤物在线精品| 免费福利视频一区二区三区| 日韩精彩视频在线观看| 亚洲综合精品四区| 国产精品久久| 日韩有吗在线观看| 亚洲视频www| 好看的av在线不卡观看| 日本高清不卡一区二区三区视频| 午夜av不卡| 福利一区视频| 老司机精品视频在线播放| 色8久久久久| 丝袜亚洲另类欧美| 婷婷激情久久| 欧美精品一二| 激情欧美一区| 亚洲精品小说| 伊人久久婷婷| 天堂日韩电影| 婷婷精品进入| 热久久久久久久| 中文字幕日韩亚洲| 欧美亚洲福利| 欧美激情三区| 日韩精品1区| 久久一区二区三区电影| 夜夜嗨网站十八久久 | 97se综合| 日韩中文在线电影| 免费不卡在线视频| 精品福利久久久| 久久久久九九精品影院| 国产欧美日韩在线观看视频 | 色8久久久久| 国产剧情一区| 日韩欧美精品综合| 国产精品嫩草99av在线| 欧美精品一区二区三区精品| 狠狠操综合网| 欧美精品中文| 在线人成日本视频| 久久高清国产| 精品国产亚洲一区二区在线观看| 成人看片网站| 黄色国产精品| 国产精品免费精品自在线观看| 日韩视频网站在线观看| 一区二区精彩视频| 91免费精品| 日韩激情中文字幕| 午夜精品婷婷| 国产精品欧美一区二区三区不卡| 久久国产精品色av免费看| 欧美男人天堂| 婷婷五月色综合香五月| 高清一区二区三区| 亚洲精品三级| 99久久久久久中文字幕一区| 91精品日本| 神马午夜久久| 欧美黄色一区二区| 综合一区二区三区| 日本精品在线中文字幕| 久久精品99国产精品日本| 午夜免费一区| 91免费精品| 精品久久不卡| 91大神在线观看线路一区| 欧美粗暴jizz性欧美20| 国产精品久久久久久久免费观看| 亚洲一区二区小说| 国产视频一区欧美| 日韩欧美中文字幕在线视频| 黑丝一区二区三区| 欧美日韩伊人| 国产欧美久久一区二区三区| 日韩成人三级| 成人国产综合| 欧美日韩亚洲三区| 日韩avvvv在线播放| 爽好多水快深点欧美视频| 黄色日韩精品|