[Day15] 若依框架二次开发改造记录:定制化之旅 contract-security-ruoyi
目录
前言
近期在开展基于若依框架的项目时,面临一些特定业务需求,需进行定制化二次开发。在此记录主要改造工作,为有类似需求的朋友提供参考。需强调的是,本模块基于若依项目二次开发,仅作学习用途,不用于盈利。
项目背景
若依作为完善的后台管理框架,在实际项目中常遭遇特殊场景:
- 多服务架构:主系统采用若依框架,同时存在其他独立部署的下游服务,需统一鉴权。例如,公司有一个核心业务系统基于若依搭建,还有一些辅助的数据分析、文件处理等下游服务,这些服务都要使用主系统的用户鉴权体系。
- Token管理需求:下游服务采用双Token机制(Access Token + Refresh Token),以提升用户体验。
- 游客访问:部分场景下,需允许未登录用户进行有限访问。就像一些电商网站,未登录用户也能浏览商品列表,但不能进行下单等操作。
- 权限精细控制:需对内部服务调用进行特殊处理。
若直接在框架中开发项目固然理想,但由于微服务架构,若强行如此,就必须将鉴权代码复制多份分发到各个微服务中。基于这些需求,开展了一系列改造工作。
主要改造内容
一、远程鉴权模块
1.1 需求场景
项目中存在独立部署的服务,而用户体系需与主系统打通。若每个服务各自维护一套用户权限,管理成本将大幅增加。因此,需实现一种机制,让下游服务能通过网络调用主系统的鉴权接口验证用户权限,如同调用本地服务般便捷,且不改变原先鉴权注解的使用方式。
1.2 实现方案
整体架构如下:
1.3 核心组件
新增ruoyi - feign模块,包含以下内容:
| 组件 | 说明 |
|---|---|
@RemotePreAuthorize |
远程鉴权注解,用法与@PreAuthorize一致 |
RemoteAuthFilter |
Servlet版鉴权过滤器 |
RemoteAuthWebFilter |
WebFlux版鉴权过滤器 |
RemoteAuthFeignService |
Feign客户端,调用主系统鉴权接口 |
UserFeignService |
用户相关的Feign客户端(暂未使用) |
1.4 使用方式
在下游服务中,使用方式如下:
// 此代码展示了在下游服务的控制器中如何使用远程鉴权注解
// 检查当前用户是否具有system:user:list权限
@RestController
@RequestMapping("/api/data")
public class DataController {
@RemotePreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/users")
public List<User> getUsers() {
// 业务逻辑,获取用户列表
return userService.getUsers();
}
}
下游服务的配置也较为简单:
- 启动类增加@EnableFeignClients并且扫描路径包括com.ruoyi.feign.service
- 有一个最基本的SpringSecurityConfig配置类来覆盖若依的Security配置,否则可能会被拦截。
// 该配置类用于启动下游服务,并启用Feign客户端
@SpringBootApplication
@EnableFeignClients(basePackages = "com.ruoyi.feign.service")
public class DownstreamApplication {
public static void main(String[] args) {
SpringApplication.run(DownstreamApplication.class, args);
}
}
1.5 支持的权限表达式
和原先的使用方式保持一致:
| 表达式 | 说明 |
|---|---|
@ss.hasPermi('system:user:list') |
检查单个权限 |
@ss.hasRole('admin') |
检查单个角色 |
@ss.hasAnyPermi('system:user:add,system:user:edit') |
检查多个权限(满足其一即可) |
@ss.hasAnyRoles('admin,manager') |
检查多个角色(满足其一即可) |
二、JWT双Token认证机制
2.1 需求场景
下游服务的前端(此处称为Contract前端)采用JWT + Refresh Token的双Token机制:
- Access Token:有效期较短(如30分钟),用于日常API调用。就像你去图书馆借书,短期的借阅证可以让你在一段时间内自由借阅书籍,但有效期一过就不能再借了。
- Refresh Token:有效期较长(如7天),用于刷新Access Token。它类似于长期的会员证,在短期借阅证过期时,可以用来获取新的短期借阅证。
这样做有诸多好处:
- 短期Token泄露风险更小。
- 用户不需要频繁重新登录。
- Refresh Token可以在服务端主动撤销。
2.2 Token流转流程
2.3 核心实现
新增了JWT工具类,支持:
| 方法 | 说明 |
|---|---|
generateAccessToken() |
生成Access Token |
generateRefreshToken() |
生成Refresh Token |
parseToken() |
解析Token |
isAccessToken() |
判断是否为Access Token |
isRefreshToken() |
判断是否为Refresh Token |
同时新增了刷新令牌管理相关的Service:
SysRefreshToken:刷新令牌实体类SysRefreshTokenMapper:Mapper接口ISysRefreshTokenService:Service接口
2.4 新增接口
| 接口 | 说明 |
|---|---|
POST /auth/refresh |
刷新Token |
POST /auth/guest |
游客登录 |
GET /auth/getInfo |
获取用户信息(适配Contract前端) |
三、游客登录功能
3.1 需求场景
某些场景下,希望允许未注册用户访问系统,但仅能进行有限操作,例如:
- 查看公开数据。
- 使用基础的分析功能。
- 体验部分产品功能。
这就需要游客登录功能。
3.2 实现方式
游客登录流程:
核心实现:
- 游客用户特征:用户名为
guest_+ 随机字符串。 - 默认角色:GUEST角色。
- 默认权限:只有查看和分析权限。
- Token有效期:与普通用户一致。
3.3 使用方式
前端调用:
// 游客登录的前端请求示例
// 向/auth/guest发送POST请求进行游客登录
POST /auth/guest
// 响应示例,返回游客相关信息
{
"code": 200,
"msg": "操作成功",
"data": {
"user": {
"id": "guest_123456",
"username": "guest_123456",
"role": "GUEST"
},
"accessToken": "xxx",
"refreshToken": "yyy",
"expiresIn": 1800
}
}
系统配置:
-- 在sys_config表中添加配置,用于控制游客登录功能的开关
INSERT INTO sys_config VALUES
(100, '用户管理-游客账户', 'sys.account.guestLogin', 'false',
'是否开启游客登录功能', 'Y', 'admin', NOW(), '', NULL, '游客登录开关');
四、内部服务免鉴权
4.1 需求场景
某些内部服务之间的调用,如主系统调用下游服务,无需经过完整的用户权限验证。此时需要一种机制来识别并豁免这类请求。
4.2 实现方式
新增内部免鉴权配置,和鉴权中心使用同一个密钥进行比对。可能有人担心安全问题,实际上目前考虑到的风险是内部调用注册中心分发这段网络被劫持,不过若这段网络都被劫持,那需要担心的就不只是密钥泄露问题了。要明白攻防是资源的权衡,并非纸上谈兵,不必钻牛角尖。
# 内部服务免鉴权配置,配置密钥
ruoyi:
remote-auth:
secret: SaltyFishSecretValue
通过特定的请求头或IP白名单来识别内部服务调用,跳过权限验证。
技术要点总结
1. 模块化设计
将远程鉴权功能独立成ruoyi - feign模块,带来诸多优势:
- 代码结构清晰,各模块职责单一。
- 其他服务引入使用方便。
- 便于维护和升级。
2. 兼容性考虑
所有改造都确保与原若依框架兼容:
- 原有的登录、鉴权方式不受影响。
- 新功能通过开关控制,可灵活开启/关闭。
- 下游服务和主系统可独立升级。
3. 安全性考虑
- 采用Token过期机制。
- 将Refresh Token存储在数据库,支持撤销。
- 设置IP白名单限制。
- 内部服务调用使用特定Token。
4. 用户体验
- 双Token机制减少登录次数。
- 游客功能降低使用门槛。
- 统一的鉴权方式,提供一致的使用体验。
使用建议
1. 生产环境配置
- 修改JWT密钥为强密钥。
- 使用HTTPS传输Token。
- 合理设置Token有效期。
2. 权限管理
- 定期审查接口权限配置。
- 严格限制游客权限。
- 妥善保管内部服务Token。
3. 监控告警
- 监控Token刷新频率。
- 记录鉴权失败日志。
- 设置异常访问告警。
写在最后
以上即为主要改造工作,整体未改变若依框架的核心设计理念,仅在特定场景下进行扩展与增强。若大家有类似需求,可参考这些改造方案,欢迎交流讨论。
下期老样子还是聊聊开发过程中遇到的一些问题。
标签:若依框架、二次开发、远程鉴权、JWT双Token、游客登录、内部服务免鉴权
更多推荐




所有评论(0)