ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Sa-Token 二级认证(安全认证)实战指南:敏感操作二次验证的完整实现

Sa-Token 二级认证(安全认证)实战指南:敏感操作二次验证的完整实现 Sa-Token 二级认证安全认证实战指南敏感操作二次验证的完整实现【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token导读本文基于 Sa-Token 开源权限认证框架系统讲解二级认证安全认证这一高级特性它允许在已登录会话的基础上对删除仓库、修改密码、提现转账等敏感操作进行二次验证通过短期、细粒度、可随时撤销的认证标记来提升会话安全性。读完本文你将掌握StpUtil.openSafe / isSafe / checkSafe / getSafeTime / closeSafe五大 API 的用法与底层原理、业务标识service驱动的多业务线认证隔离方案以及SaCheckSafe注解式校验的配置方式并能在真实项目中直接落地这套敏感操作二次确认的完整流程。一、什么是二级认证为什么要二次验证在常规鉴权体系中用户登录成功后会获得一个长期有效的会话凭证Token此后所有接口都可直接访问。但在某些敏感操作场景下仅凭登录状态是不够的——比如代码托管平台的仓库删除操作尽管用户已经登录点击[删除]按钮时仍需要再次输入密码。这么做主要为了两点保证操作者是当前账号本人防止账号被盗用后攻击者凭已登录会话直接执行破坏性操作增加操作步骤防止误操作人为增加一道确认门槛避免用户在匆忙中误删重要数据。Sa-Token 将这种能力封装为二级认证在文档与源码中亦称安全认证 Safe Auth在已登录会话的基础上进行再次验证提高会话的安全性。它的典型特征是认证结果带有有效期如 120 秒过期后需重新验证既保证安全又不至于频繁打扰用户。二、核心 API 一览五大方法搞定二级认证在 Sa-Token 中开启二级认证非常简单全部能力收敛在StpUtil门面类中实际委托给StpLogic见 sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java// 在当前会话 开启二级认证时间为120秒 StpUtil.openSafe(120); // 获取当前会话是否处于二级认证时间内 StpUtil.isSafe(); // 检查当前会话是否已通过二级认证如未通过则抛出异常 StpUtil.checkSafe(); // 获取当前会话的二级认证剩余有效时间 (单位: 秒, 返回-2代表尚未通过二级认证) StpUtil.getSafeTime(); // 在当前会话 结束二级认证 StpUtil.closeSafe();各方法语义如下表方法作用未认证时的行为openSafe(safeTime)开启二级认证safeTime为维持时间秒若未登录则抛出NotLoginExceptionisSafe()判断当前会话是否处于二级认证时间内返回false不抛异常checkSafe()校验当前会话是否已通过二级认证抛出NotSafeExceptiongetSafeTime()查询二级认证剩余有效时间秒返回-2即NOT_VALUE_EXPIREcloseSafe()结束当前会话的二级认证无操作正常返回提示openSafe()与checkSafe()在底层都会先执行checkLogin()见 StpLogic.java因此二级认证必须建立在已登录会话之上这也是二级一词的由来。三、完整业务示例删除仓库前的二次验证一个完整的二级认证业务流程如下代码与官方示例 SafeAuthController.java 保持一致// 删除仓库 RequestMapping(deleteProject) public SaResult deleteProject(String projectId) { // 第1步先检查当前会话是否已完成二级认证 if(!StpUtil.isSafe()) { return SaResult.error(仓库删除失败请完成二级认证后再次访问接口); } // 第2步如果已完成二级认证则开始执行业务逻辑 // ... // 第3步返回结果 return SaResult.ok(仓库删除成功); } // 提供密码进行二级认证 RequestMapping(openSafe) public SaResult openSafe(String password) { // 比对密码此处只是举例真实项目时可拿其它参数进行校验 if(123456.equals(password)) { // 比对成功为当前会话打开二级认证有效期为120秒 StpUtil.openSafe(120); return SaResult.ok(二级认证成功); } // 如果密码校验失败则二级认证也会失败 return SaResult.error(二级认证失败); }完整的调用步骤前后端协作流程前端调用deleteProject接口尝试删除仓库。后端校验会话尚未完成二级认证返回仓库删除失败请完成二级认证后再次访问接口。前端将信息提示给用户用户输入密码调用openSafe接口。后端比对用户输入的密码完成二级认证有效期为120 秒。前端在 120 秒内再次调用deleteProject接口尝试删除仓库。后端校验会话已完成二级认证返回仓库删除成功。可在本地直接跑通的完整示例仓库的 sa-token-demo/sa-token-demo-case 模块中提供了可运行的真实示例 SafeAuthController.java其注释中给出了完整的自测步骤前提先调用登录接口登录示例登录代码在com.pj.cases.use.LoginAuthControllerhttp://localhost:8081/acc/doLogin?namezhangpwd123456删除仓库未认证时会被拒绝http://localhost:8081/safe/deleteProject提供密码完成认证http://localhost:8081/safe/openSafe?password123456120 秒内再次删除仓库即可成功手动关闭二级认证http://localhost:8081/safe/closeSafe手动判断 or 直接抛出异常在deleteProject中我们使用了isSafe()手动判断并返回业务提示而当希望校验不通过直接中断请求时可使用StpUtil.checkSafe()或注解SaCheckSafe——二者在校验失败时会抛出NotSafeException异常错误码11071见 StpLogic.java交由全局异常处理器统一返回无需在业务代码中编写 if 判断。四、指定业务标识多业务线二级认证隔离如果项目有多条业务线都需要敏感操作验证如删除仓库用密码、查看客户端秘钥用手势密码、提现用短信验证码则无参的StpUtil.openSafe()无法提供细粒度的认证操作。此时可以指定一个**业务标识service**来分辨不同的业务线// 在当前会话 开启二级认证业务标识为client时间为600秒 StpUtil.openSafe(client, 600); // 获取当前会话是否已完成指定业务的二级认证 StpUtil.isSafe(client); // 校验当前会话是否已完成指定业务的二级认证如未认证则抛出异常 StpUtil.checkSafe(client); // 获取当前会话指定业务二级认证剩余有效时间 (单位: 秒, 返回-2代表尚未通过二级认证) StpUtil.getSafeTime(client); // 在当前会话 结束指定业务标识的二级认证 StpUtil.closeSafe(client);业务标识可以填写任意字符串不同业务标识之间的认证互不影响例如// 打开了业务标识为 client 的二级认证 StpUtil.openSafe(client); // 判断是否处于 shop 的二级认证会返回 false StpUtil.isSafe(shop); // 返回 false // 也不会通过校验会抛出异常 StpUtil.checkSafe(shop);注意无参版openSafe()等价于openSafe(important, safeTime)——默认业务标识常量DEFAULT_SAFE_AUTH_SERVICE important定义于 SaTokenConsts.java。因此文档示例中的StpUtil.openSafe(120)与StpUtil.checkSafe()实际上是围绕important这一默认业务在运作。底层存储原理一个标记键值对而已从源码看二级认证的实现非常轻量本质就是往缓存里写一个带有效期的标记见 StpLogic.javapublic void openSafe(String service, long safeTime) { // 1、开启二级认证前必须处于登录状态否则抛出异常 checkLogin(); // 2、写入指定的可以标记打开二级认证 String tokenValue getTokenValueNotNull(); getSaTokenDao().set(splicingKeySafe(tokenValue, service), SaTokenConsts.SAFE_AUTH_SAVE_VALUE, safeTime); // 3、发布事件某某 token 令牌开启了二级认证 SaTokenEventCenter.doOpenSafe(loginType, tokenValue, service, safeTime); }其中 key 的拼接规则见 StpLogic.java为格式Token名称:账号类型:safe:业务标识:Token值 形如satoken:login:safe:important:gr_SwoIN0MC1ewxHX_vfCW3BothWDZMMtx__由此可以清晰理解几个行为二级认证状态与 Token 绑定key 中含 tokenValue换一个 Token 就视为未认证与业务标识强隔离key 中含 service不同业务线互不干扰isSafe()的判定就是检查该 key 在缓存中是否存在且未过期StpLogic.java——Token 为空或未登录时直接视为未认证getSafeTime()直接委托SaTokenDao.getTimeout()查询 key 的剩余有效期未找到时返回NOT_VALUE_EXPIRE即-2见 StpLogic.javacloseSafe()直接删除该 keyStpLogic.java同时发布doCloseSafe事件。由于标记存储在 Sa-Token 统一的SaTokenDao中因此默认的内存模式、Redis 集成等一切数据存储实现都天然支持二级认证无需额外配置。五、使用注解进行二级认证SaCheckSafe在方法上标注SaCheckSafe注解可以在代码进入此方法之前自动完成一次二级认证校验校验不通过则抛出NotSafeException// 二级认证必须二级认证之后才能进入该方法 SaCheckSafe RequestMapping(add) public String add() { return 用户增加; } // 指定业务类型进行二级认证校验 SaCheckSafe(art) RequestMapping(add2) public String add2() { return 文章增加; }从注解定义SaCheckSafe.java可以看到它的两个属性value要校验的业务标识默认值为SaTokenConsts.DEFAULT_SAFE_AUTH_SERVICE即importantSaCheckSafe(art)即校验art业务的二级认证type多账号体系下所属的账号体系标识非多账号体系无需关注。注解可标注在方法或类上标注在类上等同于标注在此类的所有方法上其拦截逻辑由SaCheckSafeHandler实现见 sa-token-core/src/main/java/cn/dev33/satoken/annotation/handler/SaCheckSafeHandler.java并可与SaCheckOr组合使用实现多条件任一满足的校验策略见 SaCheckOrHandler.java。注解鉴权的通用开启方式、全局拦截器配置等可参考 注解鉴权 文档此处不再赘述。六、测试用例与事件机制框架内置的测试用例覆盖了二级认证的核心行为可作为理解与验证的依据StpLogicSafeSwitchTest.java针对StpLogic二级认证开关openSafe / isSafe / closeSafe 等的单元测试SaAnnotationHandlerTest.java覆盖SaCheckSafe注解拦截校验逻辑SaTokenEventCenterTest.java覆盖二级认证开启/关闭时的事件发布。此外二级认证的开启与关闭会触发SaTokenListener的doOpenSafe/doCloseSafe事件方便与全局监听器联动如审计日志、风控告警事件中心的定义见 SaTokenEventCenter.java相关调用见 StpLogic.java 与 StpLogic.java。七、实战要点总结使用场景删除数据、修改核心资料、提现转账、查看敏感秘钥等登录后仍需二次确认的操作。认证凭据自定密码、手势密码、短信验证码、二次扫码均可Sa-Token 只负责标记的写入与校验凭据比对逻辑完全由业务层决定。有效期控制openSafe(秒数)决定认证有效期过期后自动失效需重新认证建议按操作敏感程度设置如 120 秒 / 600 秒。多业务隔离多条业务线用不同 service 字符串互不干扰未指定时统一使用默认业务important。三种校验姿势isSafe()手动判断返回布尔值适合自定义业务提示、checkSafe()直接抛异常适合交给全局异常处理器、SaCheckSafe注解声明式校验适合固定接口。手动撤销用户主动退出敏感模式或业务完成时可调用closeSafe()提前结束认证无需等待自然过期。与登录态强关联二级认证必须建立在已登录会话之上且标记与具体 Token 绑定换端 / 重新登录后需重新认证。二级认证为 Sa-Token 的会话安全提供了一道低成本、高收益的第二道防线与登录认证、权限认证等基础能力叠加即可构建完整的分级安全体系。【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架让鉴权变得简单、优雅—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表