shiro的笔记
shiro 就是一个安全管理框架 对身份验证、授权、密码和会话管理 这些操作
这张图就可以初步了解shiro
Subject
:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject
SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器
Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。
也就是说对于我们而言,最简单的一个Shiro应用:
应用代码通过Subject来进行认证和授权,而Subject又委托给SecurityManager;
我们需要给Shiro的SecurityManager注入Realm,从而让SecurityManager能得到合法的用户及其权限进行判断。
从以上也可以看出,Shiro不提供维护用户/权限,而是通过Realm让开发人员自己注入
实战
认证-授权一组合
配置设置fiter 根据对应的设置对应就好了
1注入依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2编写自定义realm 实现realm
复写两个方法
授权
认证成功后 进行授权
认证
一般在登陆时就认证 没通过一切免谈
package com.jc.springboot_shiro.shiro; import com.jc.springboot_shiro.Service.UserService; import com.jc.springboot_shiro.domain.User; 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; public class UserRelam extends AuthorizingRealm { @Autowired UserService service; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { // 授权 得要用户吧 subject可以得到用户 Subject subject = SecurityUtils.getSubject(); User user = (User) subject.getPrincipal(); //获取用户的角色 String role = user.getRole(); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRole(role); return info; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 认证 首先得拿到 token令牌 token里面有账号密码 UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken; // 通过token来查有没有这个用户 User user = service.findbyusername(token.getUsername()); if(user !=null){ // 有这个用户 在比较密码 把正确密码带过去比对 return new SimpleAuthenticationInfo(user,user.getPassword(),getName() ); } return null; } }
3编写配置类config shiroconfig
配置类三大金刚
ShiroFilterFactoryBean->SecurityManager->realm
在bean里面编写内置过滤器 就是配置权限啥的 map
package com.jc.springboot_shiro.config; import com.jc.springboot_shiro.shiro.UserRelam; 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.HashMap; import java.util.Hashtable; import java.util.Map; // ShiroFilterFactoryBean:第三步 @Configuration public class shiroconfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); // 设置安全管理器 factoryBean.setSecurityManager(securityManager); // 这里面写拦截 规则 // 添加shiro的内置过滤器 // 认证过滤器 //anon:无需认证。 //authc:必须认证。 //authcBasic:需要通过 HTTPBasic 认证。 //user:不一定通过认证,只要曾经被 Shiro 记录即可,比如:记住我。 //授权过滤器 //perms:必须拥有某个权限才能访问。 //role:必须拥有某个角色才能访问。 //port:请求的端口必须是指定值才可以。 //rest:请求必须基于 RESTful,POST、PUT、GET、DELETE。 //ssl:必须是安全的 URL 请求,协议 HTTPS。 Map<String,String> map=new Hashtable<>(); // new一个map存放信息 map.put("/main","authc"); map.put("/main","roles[admin]"); //设置完权限后要放到fiter链里面 factoryBean.setFilterChainDefinitionMap(map); return factoryBean; } // DefaultWebSecurityManager:第二步 @Bean public DefaultWebSecurityManager securityManager(@Qualifier("userRelam") UserRelam userRelam) { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); manager.setRealm(userRelam); return manager; } // Realm:创建realm对象,需要自定义:第一步,从后往前配置 @Bean public UserRelam userRelam() { return new UserRelam(); } }
4salt盐 加密 我不会
5测试 使用
subject.login开始
@GetMapping("/login") public String main(String username , String password, Model model){ Subject subject = SecurityUtils.getSubject(); //得到subject 用户 UsernamePasswordToken token = new UsernamePasswordToken(username,password); //获取账号密码 token令牌 try { subject.login(token); //放进去认证 return "main"; } catch (AuthenticationException e) { // 账号密码有问题 就会报错 然后catch异常就好了 System.out.println( "出错" ); model.addAttribute("msg","账号密码错误"); e.printStackTrace(); return "login"; } }
subject.logout结束
写个logout的 controller 就好了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)