概述
LangChat Pro 权限体系基于 Sa-Token 框架实现,采用经典的 RBAC(Role-Based Access Control) 模型,提供完整的认证授权、权限管理、数据权限和审计日志功能。技术栈
认证框架
- Sa-Token: 1.44.0 - 轻量级Java权限认证框架
安全加密
- AES加密 - 密码加密存储
模块组成
核心组件
1. langchat-common-auth 模块
TokenConfiguration
路径:langchat-common/langchat-common-auth/src/main/java/cn/langchat/common/auth/config/TokenConfiguration.java
职责: Sa-Token全局配置
配置说明:
| 参数 | 值 | 说明 |
|---|---|---|
| tokenName | Authorization | HTTP Header中的Token名称 |
| tokenPrefix | Bearer | Token前缀,用于识别Token类型 |
| timeout | 86400秒 | Token有效时长(24小时) |
| tokenStyle | uuid | Token生成风格 |
AuthInterceptor
路径:langchat-common/langchat-common-auth/src/main/java/cn/langchat/common/auth/interceptor/AuthInterceptor.java
职责: 注册认证拦截器
实现代码:
- CaptchaInterceptor: 对
/auth/login接口进行验证码校验 - SaInterceptor: 对所有请求进行Token认证
2. langchat-auth 模块
AuthEndpoint
路径:langchat-auth/src/main/java/cn/langchat/auth/endpoint/AuthEndpoint.java
职责: 认证端点,处理登录、注册、登出等操作
核心接口:
| 接口 | 方法 | 说明 |
|---|---|---|
/auth/login | POST | 用户登录 |
/auth/info | GET | 获取用户信息 |
/auth/update/info | POST | 更新用户信息 |
/auth/update/password | POST | 修改密码 |
/auth/logout | DELETE | 用户登出 |
/auth/register | POST | 用户注册 |
/auth/email/register | POST | 邮箱注册 |
/auth/email/code | GET | 获取邮箱验证码 |
/auth/forget | POST | 忘记密码 |
用户登录流程
数据模型
核心实体
AigcUser(用户表)
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/AigcUser.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| deptId | String | 部门ID |
| username | String | 用户名 |
| password | String | 密码(AES加密) |
| realName | String | 真实姓名 |
| sex | String | 性别 |
| String | 邮箱 | |
| avatar | String | 头像URL |
| phone | String | 手机号 |
| status | Boolean | 状态(true-有效,false-锁定) |
| creator | String | 创建人 |
| createTime | Long | 创建时间 |
AigcRole(角色表)
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/AigcRole.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| name | String | 角色名称 |
| code | String | 角色别名(如:admin、user) |
| description | String | 描述 |
| creator | String | 创建人 |
| createTime | Long | 创建时间 |
AigcMenu(菜单/权限表)
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/AigcMenu.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| name | String | 资源名称 |
| parentId | String | 父级ID(树形结构) |
| path | String | 路由地址 |
| perms | String | 权限标识(如:user:list) |
| type | String | 菜单类型(button/button、menu/menu) |
| icon | String | 菜单图标 |
| component | String | 组件路径 |
| orderNo | Integer | 排序 |
| isDisabled | Boolean | 是否禁用 |
| isExt | Boolean | 是否外链 |
| isKeepalive | Boolean | 是否缓存 |
| isShow | Boolean | 是否显示 |
AigcUserRole(用户角色关联表)
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/AigcUserRole.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| userId | String | 用户ID |
| roleId | String | 角色ID |
AigcRoleMenu(角色菜单关联表)
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/AigcRoleMenu.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| roleId | String | 角色ID |
| menuId | String | 菜单ID |
AigcDept(部门表)
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/AigcDept.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| name | String | 部门名称 |
| parentId | String | 父级ID |
| orderNo | Integer | 排序 |
| createTime | Long | 创建时间 |
AigcDataAccess(数据权限表)
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/AigcDataAccess.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| table | String | 数据表名 |
| alias | String | 表别名 |
| accessType | Integer | 访问类型 |
| userId | String | 用户ID |
| deptId | String | 部门ID |
| createTime | Long | 创建时间 |
RBAC权限模型
权限模型结构
权限关联关系
权限验证流程
工具类
AuthUtil
路径:langchat-auth/src/main/java/cn/langchat/auth/utils/AuthUtil.java
核心方法:
数据权限
数据权限表(AigcDataAccess)
字段说明:| 字段 | 说明 |
|---|---|
| table | 数据表名(如:aigc_knowledge) |
| alias | 表别名(如:k) |
| accessType | 访问类型(1-全部,2-本部门,3-本部门及以下,4-仅本人) |
| userId | 用户ID |
| deptId | 部门ID |
数据权限类型
| 类型 | 说明 | SQL示例 |
|---|---|---|
| 1 | 全部数据 | - |
| 2 | 本部门数据 | AND k.dept_id = #{deptId} |
| 3 | 本部门及以下数据 | AND k.dept_id IN (子部门ID列表) |
| 4 | 仅本人数据 | AND k.creator = #{userId} |
数据权限拦截器
路径:langchat-auth/src/main/java/cn/langchat/auth/filter/KnowledgeAccessFilter.java
职责: 对知识库等资源进行数据权限过滤
操作日志
OprLog(操作日志)
路径:langchat-common/langchat-common-auth/src/main/java/cn/langchat/common/auth/entity/OprLog.java
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| userId | String | 用户ID |
| username | String | 用户名 |
| operation | String | 操作类型 |
| method | String | 请求方法 |
| params | String | 请求参数 |
| time | Long | 执行耗时 |
| ip | String | 请求IP |
| status | Boolean | 执行状态 |
| errorMsg | String | 错误信息 |
| createTime | Long | 创建时间 |
日志类型枚举
路径:langchat-auth/src/main/java/cn/langchat/auth/enums/LogEnum.java
日志记录注解
路径:langchat-common/langchat-common-core/src/main/java/cn/langchat/common/core/annotation/ApiLog.java
密码加密
加密算法
使用 AES 加密算法对用户密码进行加密存储。密码加密流程
密码验证流程
密码加密示例
会话管理
Session存储结构
Sa-Token的Session存储用户相关信息:UserInfo 结构
路径:langchat-auth/src/main/java/cn/langchat/auth/entity/UserInfo.java
会话获取示例
配置说明
application.yml 配置
权限验证流程
完整验证链路
扩展指南
添加新的权限注解
添加新的数据权限类型
- 在
AigcDataAccess表中添加新记录 - 实现对应的数据权限拦截器
- 在MyBatis Plus的拦截器中应用
添加第三方认证
集成OAuth2.0、LDAP等第三方认证:最佳实践
1. Token管理
- Token过期时间: 根据业务需求设置,一般24小时较为合理
- Token刷新: 实现Token自动刷新机制,提升用户体验
- Token黑名单: 使用Redis维护Token黑名单,支持强制登出
2. 密码安全
- 密码强度: 要求密码包含大小写字母、数字、特殊字符
- 密码过期: 定期要求用户修改密码
- 密码历史: 防止用户重复使用旧密码
3. 权限设计
- 最小权限原则: 用户只拥有完成工作所需的最小权限
- 角色分离: 区分管理员、普通用户、访客等角色
- 权限分组: 将相关权限分组,便于管理
4. 日志审计
- 关键操作记录: 记录登录、登出、敏感数据访问等操作
- 日志保留: 根据合规要求保留日志一定时间
- 日志分析: 定期分析日志,发现异常行为
5. 安全考虑
- HTTPS: 生产环境必须使用HTTPS
- 防XSS: 对输入进行转义和过滤
- 防CSRF: 使用Token验证防止跨站请求伪造
- 频率限制: 限制登录尝试次数,防止暴力破解
参考文档
- 01-整体架构概览.md
- Sa-Token官方文档: https://sa-token.dev337.cn/

