Shiro 核心知识
1. 简单介绍
Apache Shiro是一个轻量级且功能强大的开源安全框架,基于角色的权限验证RBAC(Role Base Access Control),可以进行身份验证(登录)、授权(访问权限)、会话管理和加密,含有单点登录SSO、记住我、注销和缓存功能,URL和注解都可以实现鉴权和授权,但鉴权一般通过URL控制,而授权一般通过注解控制。
2. shiro架构
A. Subject:当前与软件进行交互的实体,如用户;
B. SecurityManage:安全管理器,用于协调其托管组件以确保他们能够顺利进行协同工作;
C. Authentication:用户身份识别,通常被称为用户‘登录’;
D. Authorization:确定用户在该应用程序中的访问控制权限;
E. SessionManager:创建和管理用户的session生命周期会话管理;
F. CacheManager:创建和管理Cache组件使用实例的生命周期;
G. Cryptography:对数据源数据进行加密算法;
H. Realms:充当Shiro与应用程序之间的安全桥梁,获取应用程序中的用户、角色和权限信息,进行份验证和授权,需自己实现。
3. FilterChain:基于短路机制,即最先匹配原则,所以一般将/**=anthc放在最后面
过滤器名 | 类名 | 备注 |
anon | org.apache.shiro.web.filter.authc.AnonymousFilter | 匿名拦截器,即不需要登录即可访问,一般用于静态资源过滤,如:/static/**=anon |
authc | org.apache.shiro.web.filter.authc.FormAuthenticationFilter | 基于表单拦截器,所有已登录用户可访问,即没有登录会跳转到登录页面,如:/**=anthc |
user | org.apache.shiro.web.filter.authc.UserFilter | 用户拦截器,即用户已经身份验证或记住我登录的,如:/**=user |
authcBasic | org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter | Basic Http身份验证拦截器 |
perms | org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter | 权限授权拦截器,验证用户是否拥有所属权限,属性和roles一样,如:user/**=perms["user:create"] |
port | org.apache.shiro.web.filter.authz.PortFilter | 端口拦截器,主要属性port(80) :可以通过的端口;示例/test= port[80] ,如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样 |
rest | org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter | rest风格拦截器,自动根据请求方法构建权限字符串;示例/users=rest[user] ,会自动拼出user:read,user:create,user:update,user:delete权限字符串进行权限匹配(所有都得匹配,isPermittedAll) |
roles | org.apache.shiro.web.filter.authz.RolesAuthorizationFilter | 角色授权拦截器,验证用户是否拥有所属角色;示例/admin/**=roles[admin] |
ssl | org.apache.shiro.web.filter.authz.SslFilter | SSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口443;其他和port拦截器一样; |
logout | org.apache.shiro.web.filter.authz.LogoutFilter | 退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址(/),示例/logout=logout |
4. 认证和授权实现
(1) 登录认证:在应用程序中自定义一个继承了AuthorizingRelam抽象类的Relam类,重写doGetAuthenticationInfo方法
A. 检查提交的进行认证令牌信息(principals:唯一标识subject的用户名或邮箱等,credentials:证明身份的证据,一般就是密码)【UsernamepasswordToken是最常见的用户名/密码身份验证方法,可以自定义继承AuthenticationToken接口即可】;
B. 根据令牌信息从数据源中获取令牌信息;
C. 对用户信息进行匹配验证【SecurityUtils.getSubject().login(token)】;
D. 验证通过将返回一个封装了用户信息的AuthenticationInfo实例,验证失败则抛出AuthenticationException(层次结构很丰富)异常信息。
(2) 权限授权:在应用程序中自定义一个继承AuthorizingRelam抽象类的Relam类,重写doGetAuthorizationInfo方法,当访问到页面的时候,链接配置了相应的权限或者Shiro标签才会执行此方法,否则不执行
A. 获取登录用户名;
B. 根据用户名去数据源查询用户角色和权限;
C. 添加用户角色和权限【SimpleAuthorizationInfo类addRole()和addStringPermission()】。
(3) 登录:只是处理登录的异常信息,具体的验证交给了Shiro处理,获取异常信息【request.getAttribute("shiroLoginFailure")】。
认证过程源码分析参考:https://cloud.tencent.com/developer/article/1409287 或 https://www.jianshu.com/p/6abc22ec3cb8
5. Shiro配置
Shiro核心是通过Filter来实现,所以通过URL规则来进行过滤和权限校验。
6. Shiro权限注解
A. @RequiresAuthentication:表示当前的Subject已经通过login进行了身份验证;
B. @RequiresUser:表示当前的subject已经身份验证或者通过记住我登录的;
C. @RequiresGuest:表示当前的subject没有身份验证或者通过记住我登录的,即游客身份;
D. @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND):表示当前subject需要admin和user角色;
E.
:表示当前subject需要user:a或user:b权限;注意点:
A. Shiro的认证注解处理是有内定的处理顺序的,如果有多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关):@RequiresRoles —>@RequiresPermissions —>@RequiresAuthentication—>@RequiresUser—>@RequiresGuest;
B. 以上注解可用在controller或service层中,建议将注解用在controller中,因为service层使用了spring事物注解,那么shiro注解将失效;
C. shiro权限注解要生效,必须配置springAOP,通过设置shiro的SecurityManager 进行权限验证,即以下两个bean。
/** * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 * @return defaultAdvisorAutoProxyCreator */ @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; }
7. Shiro异常类型
(1) 身份认证异常
A. 未知账户/用户不存在:org.apache.shiro.authc.UnknownAccountException;
B. 账号锁定:org.apache.shiro.authc.LockedAccountException ;
C. 用户禁用:org.apache.shiro.authc.DisabledAccountException;
D. 错误的凭据:org.apache.shiro.authc.IncorrectCredentialsException ;
E. 过期的凭据:org.apache.shiro.authc.ExpiredCredentialsException ;
F. 不支持的身份令牌:org.apache.shiro.authc.pam.UnsupportedTokenException ;
G. 登录重试次数超限:org.apache.shiro.authc.ExcessiveAttemptsException;
H. 不允许用户多次登录:org.apache.shiro.authc.ConcurrentAccessException;
(2) 权限异常
A. 没有访问权限:org.apache.shiro.authz.HostUnauthorizedException、org.apache.shiro.authz.UnauthorizedException;
(3) 授权异常:org.apache.shiro.authz.UnauthenticatedException、org.apache.shiro.authz.AuthorizationException
(4) shiro全局异常:org.apache.shiro.ShiroException
8. Shiro缓存机制
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗