role: user

type: text

text:
<user_query>
Explore the gateway module under /Users/kazusa/IdeaProjects/baoshi/wms/ to understand the authentication and authorization logic. Specifically find:

1. The gateway module directory structure
2. How the gateway validates JWT tokens or session tokens
3. The authentication filter/interceptor code
4. Token parsing logic - what fields are in the token, how it's verified
5. What headers the gateway passes to downstream services after auth
6. Any auth configuration (which paths are public/protected)
7. The token/JWT related utility classes

Also check /Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/ for any auth-related utility classes (AuthContext, token utils, etc.)

Return all relevant file contents and paths.
</user_query>


role: assistant

text: 正在探索 gateway 模块的认证和授权逻辑。先定位 gateway 模块的位置和结构。


text: 读取关键文件以了解认证和授权逻辑：


text: 查找更多相关配置和常量文件：


text: 读取常量文件和枚举类：


text: 查看 gateway 模块的目录结构和配置文件：


text:
## Gateway 模块认证和授权逻辑分析报告

### 1. Gateway 模块目录结构

Gateway 模块位于：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-gateway-service/baoshi-gateway-server/`

主要文件结构：
```
baoshi-gateway-server/
├── src/main/java/com/baoshi/gateway/server/
│   ├── filter/
│   │   ├── UserGlobalFilter.java          # 主要认证过滤器
│   │   └── GateWayWebFilter.java          # Web过滤器（空实现）
│   ├── util/
│   │   ├── AuthenticationUtil.java        # 认证工具类（白名单验证）
│   │   └── PermissionUtil.java            # 权限验证工具类
│   ├── config/
│   │   ├── GatewayConfig.java             # 网关配置
│   │   ├── CorsConfig.java                # CORS配置
│   │   └── ApplicationConfig.java
│   ├── exceptions/
│   │   └── GatewayExceptionHandler.java   # 异常处理
│   └── GatewayApplication.java            # 启动类
```

### 2. JWT Token 验证逻辑

#### 2.1 Token 验证流程（UserGlobalFilter.java）

主要验证步骤（第120-146行）：
1. 检查请求来源（Source header）是否有效
2. 检查是否携带 token（Authorization header）
3. 使用 `JwtUtil.verifyAndGet()` 验证 JWT 签名和有效性
4. 从 JWT 的 `subject` 字段提取用户ID
5. 构建 Redis key：`user:{type}:{userId}`
6. 检查 Redis 中是否存在用户信息
7. 验证 Redis 中的 token 是否与请求的 token 一致（防止重复登录）

#### 2.2 JWT Token 结构（JwtUtil.java）

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common/src/main/java/com/baoshi/common/util/JwtUtil.java`

JWT 字段：
- `id`: UUID（JWT ID）
- `subject`: 用户ID（String）
- `issuedAt`: 签发时间
- `expiration`: 过期时间
- 签名算法：HS256
- 密钥：`"SWMS-JWT"`（硬编码）

Token 创建方法（第21-31行）：
```java
public static String create(User user, Long expireVal) {
    Date date = new Date();
    return Jwts.builder()
            .setId(UUID.randomUUID().toString())
            .setSubject(String.valueOf(user.getId()))
            .setIssuedAt(date)
            .setExpiration(new Date(date.getTime() + expireVal))
            .signWith(SignatureAlgorithm.HS256, SECRET)
            .compact();
}
```

### 3. 认证过滤器/拦截器

#### 3.1 UserGlobalFilter（主要认证过滤器）

文件：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-gateway-service/baoshi-gateway-server/src/main/java/com/baoshi/gateway/server/filter/UserGlobalFilter.java`

核心逻辑（第72-109行）：
1. 获取请求信息：IP、路径、token、来源类型、版本号
2. SSE 请求直接放行
3. 白名单检查（IP、URL、IP-URL 组合）
4. 非白名单请求进行 token 验证
5. 验证通过后设置用户上下文（AuthContext）
6. 添加自定义请求头传递给下游服务
7. WEB 来源请求进行权限验证

### 4. Token 解析逻辑

#### 4.1 JWT 解析（JwtUtil.java）

验证方法（第33-39行）：
```java
public static Claims verifyAndGet(String token) {
    try{
        return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
    }catch (Exception e) {
        return null;
    }
}
```

解析出的字段：
- `subject`: 用户ID（用于构建 Redis key）
- `issuedAt`: 签发时间
- `expiration`: 过期时间
- `id`: JWT ID

#### 4.2 Redis 用户信息结构

Redis Key 格式：`user:{source}:{userId}`

例如：`user:WEB:123`、`user:APP:456`

存储内容：User 对象的 JSON 字符串，包含：
- `id`: 用户ID
- `source`: 请求来源（WEB/APP/CUSTOMER等）
- `token`: 当前 token
- `username`: 用户名
- `role`: 角色
- `dataPermission`: 数据权限
- `version`: 版本号
- 其他字段

### 5. 传递给下游服务的 Headers

在 `UserGlobalFilter` 中（第95-97行），网关会添加以下请求头：

1. `User-Key`: Redis 用户信息 key（格式：`user:{source}:{userId}`）
2. `Version`: 客户端版本号

注意：原始的 `Authorization` 和 `Source` 头也会传递给下游服务（通过 FeignTenantInterceptor）。

#### 5.1 FeignTenantInterceptor（微服务间调用）

文件：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common-micro-spring-boot-starter/src/main/java/com/baoshi/micro/config/FeignTenantInterceptor.java`

在微服务间调用时，会添加以下请求头（第55-58行）：
- `Authorization`: 用户 token
- `Source`: 请求来源
- `Version`: 版本号
- `User-Key`: Redis key
- `X-Trace-Id`: 链路追踪ID

#### 5.2 UserFilter（下游服务过滤器）

文件：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common-micro-spring-boot-starter/src/main/java/com/baoshi/micro/filter/UserFilter.java`

下游服务从请求头读取：
- `User-Key`: 从 Redis 获取用户信息并设置到 `AuthContext`
- `Version`: 设置到用户对象
- `X-Trace-Id`: 设置链路追踪ID

### 6. 认证配置（公开/受保护路径）

#### 6.1 白名单配置（UrlWhiteConsts.java）

文件：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common/src/main/java/com/baoshi/common/constant/UrlWhiteConsts.java`

三种白名单机制：

1. IP 白名单（第168-170行）：
   - `58.33.243.165`

2. URL 白名单（第18-163行）：
   按服务前缀配置，例如：
   - `api/user`: login, loginApp, check 等
   - `api/erp`: check, we-chat/*, waybill/push 等
   - `api/robot`: external/hk/*, external/zs/* 等
   - 支持通配符 `*`

3. IP-URL 组合白名单（第177-194行）：
   - 特定 IP 访问特定路径
   - 例如：`47.103.131.176` → `/oapi/device/check/waybill/create`

#### 6.2 白名单验证逻辑（AuthenticationUtil.java）

文件：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-gateway-service/baoshi-gateway-server/src/main/java/com/baoshi/gateway/server/util/AuthenticationUtil.java`

- `routeAuth(path)`: 检查路径是否在白名单
- `ipRouteAuth(ip, path)`: 检查 IP-URL 组合是否在白名单
- 支持路径通配符匹配

### 7. Token/JWT 相关工具类

#### 7.1 JwtUtil

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common/src/main/java/com/baoshi/common/util/JwtUtil.java`

功能：
- `create(User user, Long expireVal)`: 创建 JWT token
- `verifyAndGet(String token)`: 验证并解析 JWT

#### 7.2 TokenUtils

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common-data/src/main/java/com/baoshi/basis/util/TokenUtils.java`

功能：
- `getUser(Long user, ServerEnum server)`: 从 Redis 获取用户信息
- `setUser(ServerEnum server, User user)`: 保存用户信息到 Redis
- `refresh()`: 刷新 token
- `verifyAndGetUser(String token, ServerEnum server)`: 验证 token 并获取用户

#### 7.3 AuthContext

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common/src/main/java/com/baoshi/common/system/AuthContext.java`

功能：
- `getUser()`: 获取当前线程用户信息（ThreadLocal）
- `setUser(User info)`: 设置用户信息
- `removeUser()`: 清除用户信息
- `isAdmin()`: 判断是否为管理员
- `getDataPermission()`: 获取数据权限
- `hasWarehouseDataPermission()`: 检查仓库权限
- `hasOwnerDataPermission()`: 检查货主权限

### 8. 相关常量类

#### 8.1 CustomHttpHeaderConsts

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common/src/main/java/com/baoshi/common/constant/CustomHttpHeaderConsts.java`

定义的请求头：
- `SOURCE = "Source"`: 请求来源
- `USER_KEY = "User-Key"`: 用户标识 key
- `MESSAGE_ID = "Message-Id"`: 幂等ID
- `VERSION = "Version"`: 系统版本
- `TRACE_ID = "X-Trace-Id"`: 链路追踪ID

#### 8.2 RedisConsts

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common/src/main/java/com/baoshi/common/constant/RedisConsts.java`

相关方法：
- `USER_KEY(String id, String type)`: 构建用户 Redis key
- `USER_PER_KEY(Long id, String method)`: 构建用户权限 key
- `USER_PUB_PER(String method)`: 构建公共权限 key

#### 8.3 ServerEnum

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-common/common/src/main/java/com/baoshi/common/eum/ServerEnum.java`

支持的请求来源：
- `WEB`: 24小时过期
- `CUSTOMER`: 24小时过期
- `APP`: 7天过期
- `OTHER`: 30天过期
- `CRM`: 24小时过期
- `TOOL`: 30天过期

### 9. 权限验证逻辑

#### PermissionUtil.java

位置：`/Users/kazusa/IdeaProjects/baoshi/wms/baoshi-gateway-service/baoshi-gateway-server/src/main/java/com/baoshi/gateway/server/util/PermissionUtil.java`

验证流程（第44-64行）：
1. 超级管理员直接通过
2. 检查公共权限（Redis key: `user:permission:public:{method}`）
3. 检查个人权限（Redis key: `user:{method}:{userId}`）
4. 支持路径通配符匹配

### 总结

认证授权流程：
1. 请求到达网关 → `UserGlobalFilter` 拦截
2. 检查白名单（IP/URL/IP-URL）
3. 非白名单请求验证 JWT token
4. 从 Redis 获取用户信息并验证
5. 设置用户上下文（AuthContext）
6. 添加 `User-Key` 和 `Version` 请求头
7. WEB 来源请求进行权限验证
8. 请求转发到下游服务
9. 下游服务通过 `UserFilter` 从 `User-Key` 恢复用户信息

关键文件路径已列出，可直接查看完整代码。