Shiro基础
Shiro
介绍
什么是shiro?
Apache Shiro 是一个ava 的安全(权限)框架。
Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在javaSE环境,也可以用在JavaEE环境
Shiro可以完成,认证,授权,加密,会话管理,Web集成,缓存等
-

架构
外部

subject:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject,subject代表了当前的用户,这个用户不一定是一个具体的人,与当前立用交互的任何东西都是Subject,如网络爬虫,机器人等,与Subject的所有交互都会委托给SecurityManager;subject其实是一个门面,SecurityManageer才是实际的执行者SecurityManager:安全管理器,即所有与安全有关自]操作都会与SercurityManager交互,并且它管理着所有的Subject,可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVc的DispatcherServlet的角色Realm:Shiro从Realm获取安全数据(如用户,角色权限),就是说SecurityManager要验证用户身份那么它需要从Realm获取相应的用户进行比较,来确”定用户的身份是否合法;也需要从Realm得到用户相应的角色、权限,进行验证用户的操作是否能够进行,可把Realm看成Datasource;
内部

Subject:任何可以与应用交互的’用户’,Security Manager:相当于SpringMVC中的DispatcherServlet;是Shiro的心脏,所有具体的交互都通过Security Manager进行控制,它管理者所有的Subject,且负责进行认证,授权,会话,及缓存的管理。Authenticator:负责Subject认证,是一个扩展点,可以自定义实现;可以使用认证策略(AuthenticationStrategy),即什么情况下算用户认证通过了;Authorizer:授权器,即访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的那些功能;Realm:可以有一个或者多个的realm,可以认为是安全实体数据源,即用于获取安全实体的,可以用IDBC实现,也可以是内存实现等等,由用户提供;所以一般在应用中都需要实现自己的realmSessionManager:管理Session生命周期的组件,而Shiro并不仅仅可以用在Web环境,也可以用在普通的avaSE环境中CacheManager:缓存控制器,来管理如用户,角色,权限等缓存的;因为这些数据基本上很少改变,放到缓存中后可以提高访问的性能,cryptography:密码模块,Shiro 提高了一些常见的加密组件用于密码加密,解密等
配置
(快速启动)
导入pom
配置shiro.ini

Quickstart
内容
subjet
先调用获取 对象并且获取session

判断认证

验证错误就爆出异常
(用户名不对,密码不对,错误太多锁定账户)
存储用户

角色测试(在shiro.ini里面配置)

对应角色权限测试(在shiro.ini里面配置)

最后注销

1
2
3
4
5
6
Subject currentuser=securityutils.getsubject();
Session session=currentUser.getsession();
currentUser.isAuthenticated()currentuser.getPrincipal();
currentuser.hasRole('schwartz");
currentuser.isPermitted("lightsaber:wield");
currentuser.logout();项目
Subject 用户
SecurityManager管理所有用户
Realm连接数据
先写realm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package org.example.realm; 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; public class MyRealm extends AuthorizingRealm { // 授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); if ("admin".equals(username)) { info.addRole("admin"); info.addStringPermission("user:add"); } else if ("user".equals(username)) { info.addRole("user"); } return info; }写ShiroConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45package org.example.config; import org.example.realm.MyRealm; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 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 MyRealm myRealm() { return new MyRealm(); } @Bean public SecurityManager securityManager(MyRealm myRealm) { return new DefaultWebSecurityManager(myRealm); } @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); bean.setSecurityManager(securityManager); Map<String, String> map = new LinkedHashMap<>(); map.put("/login", "anon"); map.put("/doLogin", "anon"); map.put("/logout", "logout"); map.put("/admin", "roles[admin]"); map.put("/user", "roles[user]"); map.put("/**", "authc"); bean.setFilterChainDefinitionMap(map); bean.setLoginUrl("/login"); bean.setUnauthorizedUrl("/unauthorized"); return bean; } }用户拦截
如下:
1
2
3
4
5anon:无需认证就可以访问 authc必须认证了才能访问 user:必须拥有 记住我 功能才能用 perms:拥有对某个资源的权限才能访问 role:拥有某个角色权限才能访问(在ShiroConfig写)

实现用户认证
Myrealm中写1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); String password = new String((char[]) token.getCredentials()); // 写死用户测试 if ("admin".equals(username) && "123456".equals(password)) { return new SimpleAuthenticationInfo(username, password, getName()); } if ("user".equals(username) && "111111".equals(password)) { return new SimpleAuthenticationInfo(username, password, getName()); } throw new UnknownAccountException("用户名或密码错误"); } }请求授权实现

对用户限制使用add
访问会弹出401报错(401就是未授权)
页面跳转
先在MuController添加访问路径

配置
MyController

整合Mybatis(数据库)
- 先加依赖

配置文件
1
2mybatis.type-aliases-package=org.example.shiro.pojo mybatis.mapper-locations=classpath:mapper/*.xml在pojo中写user类

写mapper里面UserMapper写

配置静态mapper

service层写UserService

UserServiceImpl

接下来就在MyRealm中写
连接真实数据库

记得把之前自己写的数据删了
区别
| 比较项 | Apache Shiro | Spring Security |
|---|---|---|
| 背景来源 | 第三方安全框架 | Spring 官方安全体系 |
| 集成性 | 较弱,需手动整合 | 深度集成 Spring Boot / Spring MVC |
| 功能复杂度 | 简单、轻量级 | 功能全面、体系庞大 |
| 认证方式 | 基于 Subject(用户) | 基于 SecurityContext(安全上下文) |
| 授权方式 | 角色/权限标注支持简单 | 支持复杂 RBAC、ACL、权限层级 |
| 会话管理 | 内置,可脱离 Web 使用 | 依赖 Servlet 容器(或额外配置) |
| 前后端分离支持 | 需自定义较多 | 原生支持 JWT / OAuth2 / Filter 链控制 |
| 企业级安全标准 | 支持少 | 内置防护更多(CSRF、会话固定攻击等) |
Shiro基础
http://example.com/2025/12/08/Shiro/