一、Shiro 核心概念
1、什么是Shiro?
特点:
易于理解的 Java Security API; 简单的身份认证(登录),支持多种数据源(LDAP,JDBC 等); 对角色的简单的签权(访问控制),也支持细粒度的鉴权; 支持一级缓存,以提升应用程序的性能; 异构客户端会话访问; 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境; 不跟任何的框架或者容器捆绑,可以独立运行。 非常简单的加密 API;
2、认证与授权的核心术语
- 权限(Permission):对资源的具体操作许可,格式通常为 “资源:操作”(如 “user:add” 表示新增用户的权限,“product:view” 表示查看商品的权限)。
- 认证(Authentication):验证 “用户是谁” 的过程,即确认用户身份的合法性(如登录时校验账号密码)。
- 授权(Authorization):验证 “用户能做什么” 的过程,即控制用户对资源的访问权限(如普通用户不能删除数据,管理员可以)。
- 角色(Role):一组权限的集合,用于简化权限管理(如 “管理员” 角色包含 “新增用户”“删除数据” 等权限)。
认证流程
授权流程
3、核心组件
- Subject(主体):代表当前操作的 “用户”(可能是实际用户、程序、定时任务等),是开发者与 Shiro 交互的入口。通过SecurityUtils.getSubject()可获取当前 Subject,所有安全操作(如登录、权限校验)都通过 Subject 触发。
- SecurityManager(安全管理器):Shiro 的 “大脑”,负责协调所有安全组件(认证、授权、会话等),是 Shiro 的核心调度中心。开发者无需直接操作 SecurityManager,只需通过 Subject 间接调用其功能。
- Realm(领域):Shiro 的 “数据源接口”,负责从数据库、缓存、配置文件等地方获取用户信息(如账号密码、权限列表)。认证时,Realm 提供用户的真实凭证;授权时,Realm 提供用户的权限集合。自定义 Realm 是 Shiro 灵活适配业务的关键。(数据库读取+认证功能+授权功能实现)
-
Authenticator(认证器):对用户登录时进行身份认证
- Authorizer(授权器):用户通过认证器认证通过,在访问功能时需要通过授权器判断用户是否有此功能的操作权限。
Shiro架构图
二、Shiro 认证
【1】认证
认证是 Shiro 安全流程的第一步,其核心是 “校验用户提供的凭证是否与系统存储的凭证一致”。Shiro 的认证流程遵循标准化步骤,同时支持多种加密方式保障凭证安全。
【2】认证流程:
1、Shiro把用户的数据封装成标识token,token一般封装着用户名,密码等信息
2、使用Subject门面获取到封装着用户的数据的标识token
3、Subject把标识token交给SecurityManager,在SecurityManager安全中心中,SecurityManager把标识token委托给认证器Authenticator进行身份验证。认证器的作用一般是用来指定如何验证,它规定本次认证用到哪些Realm
4、认证器Authenticator将传入的标识token,与数据源Realm对比,验证token是否合法
【3】编码、散列算法
三、身份授权
【1】基本流程
1、首先调用Subject.isPermitted/hasRole接口,其会委托给SecurityManager。
2、SecurityManager接着会委托给内部组件Authorizer;
3、Authorizer再将其请求委托给我们的Realm去做;Realm才是真正干活的;
4、Realm将用户请求的参数封装成权限对象。再从我们重写的doGetAuthorizationInfo方法中获取从数据库中查询到的权限集合。
5、Realm将用户传入的权限对象,与从数据库中查出来的权限对象,进行一一对比。如果用户传入的权限对象在从数据库中查出来的权限对象中,则返回true,否则返回false。
四、Shiro默认过滤器
【1】认证相关
过滤器 | 过滤器类 | 说明 |
authc
|
FormAuthenticationFilter
|
基于表单的过滤器;如“/**=authc”,如果没有登录会跳到相应的登录页面登录
|
logout
|
LogoutFilter
|
退出过滤器,主要属性:redirectUrl:退出成功后重定向的地址,如“/logout=logout”
|
anon |
AnonymousFilter
|
匿名过滤器,即不需要登录即可访问;一般用于静态资源过滤;示例“/static/**=anon”
|
【2】授权相关
过滤器
|
过滤器类
| 说明 |
roles
|
RolesAuthorizationFilter
|
角色授权拦截器,验证用户是否拥有所有角色;主要属性: loginUrl:登录页面地址(/login.jsp);unauthorizedUrl:未授权后重定向的地址;示例“/admin/**=roles[admin]
|
perms
|
PermissionsAuthorizationFilter
|
权限授权拦截器,验证用户是否拥有所有权限;属性和roles一样;示例“/user/**=perms["user:create"]”
|
port
|
PortFilter
|
端口拦截器,主要属性:port(80):可以通过的端口;示例“/test= port[80]”,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/ 参数等都一样
|
rest
|
HttpMethodPermissionFilter
|
rest风格拦截器,自动根据请求方法构建权限字符串(GET=read,POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read,
MKCOL=create)构建权限字符串;示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll)
|
ssl
|
SslFilter
|
SSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口(443);其他port拦截器一样;
|
五、Springboot集成Shiro
【1】依赖坐标与准备
数据源配置
shiro-core、shiro-spring、shiro-web、shiro-encache(前四个版本要一致)、mybatis的启动器、mysql、web启动器、test启动器
数据库表:
【2】构造生成密文密码的工具类
- 加密算法和加密次数
- 生成盐值
- 通过盐值和明文密码得到密文密码
- 将上述两个方法封装
【3】Shiro的配置类(八部分内容)
过滤器工厂(最重要):作用:设置怎样的路径请求使用怎样的过滤器
【4】MyRealm类
需要继承AuthorizingRealm,重写认证和授权的方法
认证:
- 1、从token令牌取出username
- 2、根据用户名查到这个用户的信息
- 3.为该方法创建返回值对象:SimpleAuthenticationInfo
- 4、该对象需要四个参数:安全数据、密文密码、盐值、realm类名首字母小写
授权:
- 1、从方法参数的getPrimaryPrincipal方法取出安全数据,我用的是id
- 2、通过id查询该用户的所有数据(包括角色和权限)
- 3、将角色和权限分别放到Set集合,把集合传给方法的返回值对象
注意:解密还是四要素。还需要加密算法和加密次数,通过属性初始化,使realm类初始化就具有这几个参数
【5】控制器层
控制器统一返回JSON,所以用注解@RestController,测试时使用工具既可测试,如:Postman
认证的测试,即登录方法
授权的测试,即鉴权。通过注解配置:@RequiresPermissions("user-add"),里面的内容就是权限Set集合里面的值
【6】全局异常处理器
如果鉴权发生异常,我们无法使用try-catch,那么就要使用全局异常处理器
六、总结
综上,Shiro 作为一款优秀的安全框架,在认证与授权领域为开发者提供了强大且灵活的支持。从核心概念的梳理,到认证、授权流程的深入解析,再到与 SpringBoot 的集成实践,我们能清晰看到它如何保障系统安全。无论是简单的单体应用,还是复杂的分布式系统,Shiro 都能通过简洁的配置和自定义扩展,轻松实现用户身份验证与资源权限控制,助力开发者构建安全可靠的应用系统。
感谢你花时间读到这里~ 如果你觉得这篇内容对你有帮助,不妨点个赞让更多人看到;如果有任何想法、疑问,或者想分享你的相关经历,欢迎在评论区留言交流,你的每一条互动对我来说都很珍贵~ 我们下次再见啦!😊😊