一、shiro使用必须了解的知识
1、shiro是什么?
1、Apache Shiro是一个Java的安全(权限)框架
2、可以容易的开发出足够好的应用,既可以在JavaEE中使用,也可以在JavaSE中使用
3、shiro可以完成,认证、授权、加密、会话管理,web集成、缓存等
2、shiro架构三个常用三大核心对象
Subject:用户
SecurityManager:管理所有用户
Readim:连接数据
3、在springboot中使用时,主要可将其看作两个模块(请求过滤模块、认证授权模块)
1、认证授权模块:在认证授权模块中主要包含两个方面,分别是认证和授权。认证就是指对用户登录的情况进行判定;授权就是指对当前用户所拥有的角色、权限进行获取并将其交给AuthoriztionInfo,使其能够将相关信息交给Shiro
2、请求过滤模块:根据当前用户所拥有的权限、角色等信息来进行判断是否具有请求的权限(即是否能够请求当前要访问的地址),如果该用户具有访问当前请求地址的权限,则放行,否则进行拦截
3、以上是使用shiro框架进行权限认证拦截的最基本实现,此外还可以通过对密码进行加密,登录次数限流(redis)等功能重写来按照自己实际业务情况进行学习
4、依赖
<!-- 后台拦截--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
二、具体使用
1、编写配置类(config)
1.1、Shiro过滤对象(ShiroFilterFactoryBean)
@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; }
1.2、Shiro安全对象(DefaultWebSecurity)
//@Qualifier:引入bena对象 @Bean(name="SecurityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("MyRealm") MyRealm myRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurotyManager(); //关联MyRealm securityManager.setRealm(myRealm); return securityManager; }
1.3、创建realm对象(自定义)
//将自定义的realm对象交给spring //@Bean(name="MyRealm")中name属性不加默认名称为方法名 @Bean(name="MyRealm") public MyRealm MyRealm(){ return new MyRealm(); }
2、创建realm对象
2.1、自定义realm类去继承AuthorizingRealm类
class MyRealm extends AuthorizingRealm
2.2、重写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)","") }
3、登录用户的信息传入(通过controller获取登录的请求信息)
//获取当前用户 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
三、具体实现
1、realm实现
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()); } }
2、controller实现
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,"退出失败"); } } }
3、config实现
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中如何快速实现的详细内容。更多信息请关注PHP中文网其他相关文章!

本文讨论了使用Maven和Gradle进行Java项目管理,构建自动化和依赖性解决方案,以比较其方法和优化策略。

本文使用Maven和Gradle之类的工具讨论了具有适当的版本控制和依赖关系管理的自定义Java库(JAR文件)的创建和使用。

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

本文讨论了使用JPA进行对象相关映射,并具有高级功能,例如缓存和懒惰加载。它涵盖了设置,实体映射和优化性能的最佳实践,同时突出潜在的陷阱。[159个字符]

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器