Skip to main content
注意,LangChat 的权限使用了 Sa-Token,核心配置位于 /langchat-llm-ops/langchat-llm-auth/langchat-common/langchat-common-ai

系统架构概述

LangChat Pro 采用基于 Sa-Token 的权限认证系统,实现了完整的用户认证、权限控制和会话管理功能。系统支持多种认证方式,包括用户名密码、JWT Token 等,并提供了灵活的权限控制机制。

权限模块结构

权限模块结构

认证配置

请求头 Token 配置

因为 Sa-Token 有默认的请求头名称,一般情况我们采用 Authorization 作为请求头认证 Key,具体配置如下: Token 配置 因此,访问的认证请求头如下:
Authorization: Bearer xxxxxx

认证流程

Redis 配置

会话存储配置

登录后,登录信息配置在 Redis 中,因此可以轻松的实现过期配置,相关的 Key 设置如下: Redis Key 配置

Redis 配置示例

spring:
  redis:
    host: localhost
    port: 6379
    database: 0
    timeout: 10000ms
    lettuce:
      pool:
        max-active: 8
        max-wait: -1ms
        max-idle: 8
        min-idle: 0

Sa-Token Redis 配置

sa-token:
  # Token 名称
  token-name: Authorization
  # Token 有效期
  timeout: 2592000
  # Token 临时有效期
  activity-timeout: -1
  # 是否允许同一账号并发登录
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个 Token
  is-share: false
  # Token 风格
  token-style: uuid
  # 是否输出操作日志
  is-log: false
  # 是否从 Cookie 中读取 Token
  is-read-cookie: false
  # 是否从 Header 中读取 Token
  is-read-header: true
  # 是否从 Body 中读取 Token
  is-read-body: false

请求拦截配置

拦截器配置

common 目录下放的是 Auth 相关抽离的公共配置,而应用具体的拦截配置如下: 拦截器配置
在这里配置具体拦截哪些请求,放行哪些请求

拦截器实现示例

@Component
public class AuthInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 获取请求路径
        String requestURI = request.getRequestURI();
        
        // 白名单路径直接放行
        if (isWhitePath(requestURI)) {
            return true;
        }
        
        // 验证 Token
        String token = request.getHeader("Authorization");
        if (StringUtils.isEmpty(token)) {
            throw new UnauthorizedException("Token 不能为空");
        }
        
        // 验证 Token 有效性
        if (!StpUtil.isLogin()) {
            throw new UnauthorizedException("Token 无效");
        }
        
        // 权限验证
        if (!hasPermission(requestURI)) {
            throw new ForbiddenException("权限不足");
        }
        
        return true;
    }
}

白名单配置

auth:
  white-list:
    - /auth/login
    - /auth/register
    - /public/**
    - /swagger-ui/**
    - /v3/api-docs/**

日志监听配置

对于 LLM 项目,日志文件会存储在 aigc_log 表中
日志配置

日志配置示例

logging:
  level:
    com.langchat.auth: DEBUG
    com.langchat.security: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
  file:
    name: logs/auth.log
    max-size: 100MB
    max-history: 30

权限接口

认证接口

认证接口

核心接口说明

权限控制实现

注解权限控制

@RestController
@RequestMapping("/api")
public class UserController {
    
    @SaCheckPermission("user:list")
    @GetMapping("/users")
    public Result<List<User>> getUserList() {
        // 需要 user:list 权限
        return Result.success(userService.list());
    }
    
    @SaCheckRole("admin")
    @PostMapping("/users")
    public Result<User> createUser(@RequestBody User user) {
        // 需要 admin 角色
        return Result.success(userService.save(user));
    }
}

编程式权限控制

@Service
public class UserService {
    
    public void deleteUser(Long userId) {
        // 检查是否有删除用户的权限
        if (!StpUtil.hasPermission("user:delete")) {
            throw new ForbiddenException("权限不足");
        }
        
        // 检查是否是删除自己
        if (StpUtil.getLoginIdAsLong().equals(userId)) {
            throw new ForbiddenException("不能删除自己");
        }
        
        userMapper.deleteById(userId);
    }
}

安全最佳实践

在生产环境中,请遵循以下安全最佳实践

1. Token 安全

  • 使用 HTTPS 传输
  • 设置合理的过期时间
  • 实现 Token 刷新机制
  • 支持 Token 黑名单

2. 密码安全

  • 密码加密存储(BCrypt)
  • 密码复杂度要求
  • 登录失败次数限制
  • 密码定期更换提醒

3. 权限最小化

  • 遵循最小权限原则
  • 定期审查用户权限
  • 实现权限审计日志
  • 支持动态权限调整
完成以上配置后,系统将具备完整的权限认证和访问控制能力。