<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
1、Apache Shiro是一個Java的安全(許可權)框架
2、可以容易的開發出足夠好的應用,既可以在JavaEE中使用,也可以在JavaSE中使用
3、shiro可以完成,認證、授權、加密、對談管理,web整合、快取等
Subject:使用者
SecurityManager:管理所有使用者
Readim:連線資料
1、認證授權模組:在認證授權模組中主要包含兩個方面,分別是認證和授權。認證就是指對使用者登入的情況進行判定;授權就是指對當前使用者所擁有的角色、許可權進行獲取並將其交給AuthoriztionInfo,使其能夠將相關資訊交給Shiro
2、請求過濾模組:根據當前使用者所擁有的許可權、角色等資訊來進行判斷是否具有請求的許可權(即是否能夠請求當前要存取的地址),如果該使用者具有存取當前請求地址的許可權,則放行,否則進行攔截
3、以上是使用shiro框架進行許可權認證攔截的最基本實現,此外還可以通過對密碼進行加密,登入次數限流(redis)等功能重寫來按照自己實際業務情況進行學習
<!-- 後臺攔截--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
@Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier(SecurityManager) DefaultWebSecurityManager securityManager){ ShiroFilterFactiryBean bean = new ShiroFilterFactoryBean() //關聯SecurityManager設定安全管理器 bean.setSecurityManager(securityManager) //新增內建過濾器 /* anon:無需過濾就可以存取 authc:必須認證了才可存取(登入後才可存取) user:必須擁有"記住我"功能才可存取 perms:擁有對某個資源的許可權才可以存取 role:擁有某個角色許可權才可存取 */ Map<String,String> filterMap = new LinkedHashMap<>(); //攔截 //filterMap.put("頁面地址","內建過濾器") //filterMap.put("/user/name","anon") //filterMap.put("/user/book","authc") //具有user:add許可權時才可以存取/user/name //perms中的「user:add」與資料庫中對應許可權要一致 filterMap.put("/user/name","perms[user:add]") //授權,正常情況下,沒有授權會跳轉到未授權頁面 bean.setUnauthorizedUrl("未授權時跳轉的頁面") //建立一個過濾器鏈(其中內容通過Map儲存) bean.setFilterChainDefinitionMap(FilterMap); //設定登入請求(登入的地址新增,當使用"authc"時,如果未登入,則跳轉到登入頁面) bean.setLoginUrl("/login") return bean; }
//@Qualifier:引入bena物件 @Bean(name="SecurityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("MyRealm") MyRealm myRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurotyManager(); //關聯MyRealm securityManager.setRealm(myRealm); return securityManager; }
//將自定義的realm物件交給spring //@Bean(name="MyRealm")中name屬性不加預設名稱為方法名 @Bean(name="MyRealm") public MyRealm MyRealm(){ return new MyRealm(); }
class MyRealm extends AuthorizingRealm
授權:
project AthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){ //1、許可權資訊物件info,用來存放查出的使用者的所有的角色(role)及許可權(permission) SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //2、拿到當前登入的物件資訊,通過認證方法SimpleAuthenticationInfo(第一個引數)已經進行存入 User user =(user)SecurityUtils.getSubject().getPrincipal(); //3、將該物件的角色資訊進行存入 // 賦予角色 List<Role> roleList = roleService.listRolesByUserId(userId); for (Role role : roleList) { info.addRole(role.getName()); } //4、設定該使用者的許可權 infO.addStringPermission(user.getPerms()) //5、將該物件的許可權資訊進行存入(permissionSet一個許可權資訊的集合) info.setStringPermissions(permissionSet); return info; }
認證:
project AuthenticationInfo doGetAuthorizationInfo(AuthenticationToken token){ //1、拿到使用者登陸的資訊 UsernamePasswordToken userToken =(UsernamePasswordToken) token; //2、通過使用者名稱(userToken.getUsername)獲取資料庫中的物件user //如果獲取物件user為空則該使用者不從在,返回return null(丟擲使用者不存在異常) if (user == null) { throw new UnknownAccountException("賬號不存在!"); //或直接 return null; } //3、密碼認證,有shiro完成(AuthenticationInfo是一個介面,SimpleAuthenticationInfo是其介面的實現類) //也可對密碼進行加密 如MD5 MD5鹽值 return new SimpleAuthenticationInfo("使用者物件資訊(user)","通過使用者從資料庫中獲得的使用者密碼(user.password)","") }
//獲取當前使用者 Subject subject = SecurityUtils.getSubject(); //封裝使用者的登入資料(username:使用者登陸時傳入的賬號;password:使用者登陸時傳入的密碼) UsernamePasswordToken token = new UsernamePasswordToken(username,password); //執行登入(如果有異常則登入失敗,沒有異常則登入成功,在Shiro中已經為我們封裝了登入相關的異常,直接使用即可) try{ subject.login(token);//執行登入成功後 return "首頁" }catch(UnknowAccountException e){//使用者名稱不存在 return "login" }catch(IncorrectCredentialsException e){//密碼不存在 return "login" } 注意:該方法中登入失敗後返回的是跳轉的頁面,故不可用@ResponseBody
package com.lingmeng.shiro; import com.lingmeng.pojo.entity.Admin; import com.lingmeng.pojo.entity.Permission; import com.lingmeng.pojo.entity.Role; import com.lingmeng.pojo.resp.BaseResp; import com.lingmeng.service.AdminService; import com.lingmeng.service.RoleService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashSet; import java.util.Set; public class MyRealm extends AuthorizingRealm { @Autowired RoleService roleService; @Autowired AdminService adminService; //授權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //獲取使用者資訊 Subject subject = SecurityUtils.getSubject(); Admin admin =(Admin) subject.getPrincipal(); //獲取使用者的許可權及角色資訊 BaseResp baseResp = roleService.selectOne(admin.getUsername()); Role role = (Role) baseResp.getData(); //將獲取的角色及許可權進行存入 if (role!=null){ //角色存入 info.addRole(role.getName()); //許可權資訊進行存入 Set<String> perms = new HashSet<>(); for (Permission perm : role.getPerms()) { perms.add(perm.getUrl()); } info.setStringPermissions(perms); } return info; } //認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //獲取登入資訊(登入的賬號) String username =(String)authenticationToken.getPrincipal(); // UsernamePasswordToken userToken =(UsernamePasswordToken) authenticationToken;拿到登入時傳入的賬號和密碼物件 //從資料庫中查詢該物件的資訊 Admin admin = adminService.selectOne(username); if (admin==null){ throw new UnknownAccountException("賬號不存在"); } return new SimpleAuthenticationInfo(admin,admin.getPassword(),this.getName()); } }
package com.lingmeng.controller; import com.lingmeng.pojo.entity.Admin; import com.lingmeng.pojo.resp.BaseResp; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.web.bind.annotation.*; @RestController public class AdminController { @PostMapping("background/login") public BaseResp login(@RequestBody Admin admin){ Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(admin.getUsername(), admin.getPassword()); try{ subject.login(token); return BaseResp.SUCCESS("登入成功",null,null); }catch (UnknownAccountException e){//賬號不存在 return BaseResp.FAIL(201,"賬號不存在"); }catch(IncorrectCredentialsException incorrectCredentialsException){//密碼錯誤 return BaseResp.FAIL(201,"密碼錯誤") ; } } @GetMapping("/background/exitLogin") public BaseResp exitLogin(){ Subject subject = SecurityUtils.getSubject(); System.out.println(subject.getPrincipal()); try{ subject.logout();//退出登入 return BaseResp.SUCCESS("退出登入",null,null); }catch(Exception e){ return BaseResp.FAIL(202,"退出失敗"); } } }
package com.lingmeng.config; import com.lingmeng.shiro.MyRealm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager); //設定請求攔截並存入map中 /* anon:無需過濾就可以存取 authc:必須認證了才可存取(登入後才可存取) user:必須擁有"記住我"功能才可存取 perms:擁有對某個資源的許可權才可以存取 role:擁有某個角色許可權才可存取 */ Map<String, String> map = new LinkedHashMap<>(); map.put("/background/**","authc"); map.put("background/login","anon"); bean.setFilterChainDefinitionMap(map); //設定未授權跳轉地址 bean.setUnauthorizedUrl(""); //設定登入地址 bean.setLoginUrl("/background/login"); return bean; } @Bean("securityManager") public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("myRealm") MyRealm myRealm){ return new DefaultWebSecurityManager(myRealm); } @Bean() public MyRealm myRealm(){ return new MyRealm(); } }
以上是一些shiro在springboot中的基本用法,希望能夠對大家學習有所幫助(程式碼中的實體,角色,許可權根據自己資料庫查詢結果進行替換即可)
到此這篇關於Shiro在springboot中快速實現的文章就介紹到這了,更多相關springboot實現Shiro內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45