架构设计文档¶
🏛️ 整体架构¶
分层架构¶
┌─────────────────────────────────────────────────────────┐
│ 客户端应用层 │
│ (Web/Mobile App/其他微服务) │
└────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ API网关层 │
│ (Spring Cloud Gateway / Nginx) │
│ - 路由转发 - 统一认证 - 限流熔断 │
└────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 认证授权服务 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Controller层 (API接口) │ │
│ │ - 用户管理 - 认证 - 授权 - 租户管理 │ │
│ └─────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────────▼───────────────────────────────┐ │
│ │ Service层 (业务逻辑) │ │
│ │ - UserService - AuthService - RoleService │ │
│ │ - PermissionService - TenantService │ │
│ └─────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────────▼───────────────────────────────┐ │
│ │ Security层 (安全核心) │ │
│ │ - JWT处理 - OAuth2 - 权限验证 - 加密解密 │ │
│ └─────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌─────────────────▼───────────────────────────────┐ │
│ │ Repository层 (数据访问) │ │
│ │ - UserRepository - RoleRepository │ │
│ └─────────────────┬───────────────────────────────┘ │
└────────────────────┼───────────────────────────────────┘
│
┌──────────┴──────────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ MySQL │ │ Redis │
│ 持久化存储│ │ 缓存 │
└──────────┘ └──────────┘
📦 模块划分¶
auth-common(公共模块)¶
职责:提供公共工具类、常量、异常定义等
auth-common/
├── constant/ # 常量定义
│ ├── AuthConstant.java
│ ├── CacheConstant.java
│ └── ErrorCodeConstant.java
├── enums/ # 枚举类型
│ ├── UserStatus.java
│ ├── LoginType.java
│ └── PermissionType.java
├── exception/ # 自定义异常
│ ├── AuthException.java
│ ├── TokenException.java
│ └── PermissionException.java
├── util/ # 工具类
│ ├── PasswordUtil.java
│ ├── JwtUtil.java
│ └── RedisUtil.java
└── dto/ # 数据传输对象
└── Result.java # 统一响应对象
auth-api(API接口定义)¶
职责:定义Feign接口,供其他服务调用
auth-api/
├── dto/ # 请求/响应DTO
│ ├── request/
│ │ ├── LoginRequest.java
│ │ ├── RegisterRequest.java
│ │ └── TokenRefreshRequest.java
│ └── response/
│ ├── LoginResponse.java
│ ├── UserInfoResponse.java
│ └── TokenResponse.java
├── feign/ # Feign客户端
│ ├── AuthFeignClient.java
│ └── UserFeignClient.java
└── vo/ # 视图对象
├── UserVO.java
└── RoleVO.java
auth-core(核心服务)¶
职责:核心业务逻辑实现
auth-core/
├── config/ # 配置类
│ ├── SecurityConfig.java
│ ├── RedisConfig.java
│ ├── MyBatisPlusConfig.java
│ └── Knife4jConfig.java
├── controller/ # 控制器
│ ├── AuthController.java # 认证接口
│ ├── UserController.java # 用户管理
│ ├── RoleController.java # 角色管理
│ ├── PermissionController.java # 权限管理
│ ├── TenantController.java # 租户管理
│ └── OAuthController.java # OAuth接口
├── service/ # 业务服务
│ ├── IAuthService.java
│ ├── IUserService.java
│ ├── IRoleService.java
│ ├── IPermissionService.java
│ ├── ITenantService.java
│ ├── ITokenService.java
│ └── impl/
│ ├── AuthServiceImpl.java
│ ├── UserServiceImpl.java
│ └── ...
├── security/ # 安全相关
│ ├── jwt/
│ │ ├── JwtTokenProvider.java
│ │ ├── JwtAuthenticationFilter.java
│ │ └── JwtAuthenticationEntryPoint.java
│ ├── oauth2/
│ │ ├── OAuth2AuthorizationServer.java
│ │ └── OAuth2ResourceServer.java
│ ├── handler/
│ │ ├── LoginSuccessHandler.java
│ │ ├── LoginFailureHandler.java
│ │ └── LogoutHandler.java
│ └── userdetails/
│ └── CustomUserDetailsService.java
├── repository/ # 数据访问
│ ├── mapper/
│ │ ├── UserMapper.java
│ │ ├── RoleMapper.java
│ │ ├── PermissionMapper.java
│ │ └── TenantMapper.java
│ └── entity/
│ ├── User.java
│ ├── Role.java
│ ├── Permission.java
│ ├── UserRole.java
│ ├── RolePermission.java
│ └── Tenant.java
├── interceptor/ # 拦截器
│ ├── TenantInterceptor.java
│ └── LogInterceptor.java
├── aspect/ # 切面
│ ├── LogAspect.java
│ └── PermissionAspect.java
└── cache/ # 缓存管理
├── UserCacheService.java
└── PermissionCacheService.java
auth-client(客户端SDK)¶
职责:提供Spring Boot Starter,方便其他服务集成
auth-client/
├── autoconfigure/
│ ├── AuthAutoConfiguration.java
│ ├── AuthProperties.java
│ └── AuthClientConfiguration.java
├── annotation/
│ ├── RequirePermission.java # 权限注解
│ ├── RequireRole.java # 角色注解
│ └── RequireLogin.java # 登录注解
├── interceptor/
│ ├── AuthInterceptor.java # 认证拦截器
│ └── PermissionInterceptor.java # 权限拦截器
├── filter/
│ └── TokenFilter.java # Token过滤器
├── context/
│ └── UserContext.java # 用户上下文
└── resources/
└── META-INF/
└── spring.factories # 自动配置
🔐 认证流程¶
1. 用户登录流程¶
用户 → 发送登录请求(username/password)
↓
AuthController.login()
↓
AuthService.authenticate()
├─ 验证用户名密码
├─ 检查用户状态
├─ 检查租户状态
├─ 记录登录日志
└─ 生成Token
↓
返回 AccessToken + RefreshToken
↓
客户端存储Token
2. Token验证流程¶
客户端 → 携带Token访问资源
↓
JwtAuthenticationFilter
├─ 提取Token
├─ 验证Token有效性
├─ 解析用户信息
├─ 检查Redis黑名单
└─ 加载用户权限
↓
设置SecurityContext
↓
继续请求处理
3. 权限验证流程¶
请求接口
↓
PermissionInterceptor/PermissionAspect
├─ 获取当前用户
├─ 获取所需权限
├─ 从缓存获取用户权限
└─ 权限匹配
↓
通过:继续执行
失败:返回403
🎫 Token设计¶
Token类型¶
- Access Token
- 有效期:2小时
- 用途:访问资源
-
存储位置:客户端(Header/LocalStorage)
-
Refresh Token
- 有效期:7天
- 用途:刷新Access Token
- 存储位置:客户端(HttpOnly Cookie)
Token结构¶
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"userId": "1001",
"username": "zhangsan",
"tenantId": "T001",
"roles": ["admin", "user"],
"permissions": ["user:read", "user:write"],
"exp": 1698765432,
"iat": 1698758232,
"jti": "token-unique-id"
},
"signature": "..."
}
🗄️ 缓存设计¶
Redis缓存策略¶
| 缓存Key | 数据 | 过期时间 | 说明 |
|---|---|---|---|
auth:user:{userId} |
用户信息 | 30分钟 | 用户基本信息 |
auth:permissions:{userId} |
用户权限列表 | 30分钟 | 用户所有权限 |
auth:roles:{userId} |
用户角色列表 | 30分钟 | 用户所有角色 |
auth:token:blacklist:{jti} |
Token标识 | Token过期时间 | Token黑名单 |
auth:login:fail:{username} |
失败次数 | 15分钟 | 登录失败计数 |
auth:online:user:{userId} |
会话信息 | 30分钟 | 在线用户 |
auth:tenant:{tenantId} |
租户配置 | 1小时 | 租户信息 |
缓存更新策略¶
- 主动更新:数据修改时主动删除缓存
- 被动更新:缓存过期后重新加载
- 异步刷新:后台定时刷新热点数据
🔄 OAuth 2.0实现¶
支持的授权模式¶
- 授权码模式(Authorization Code)
- 适用场景:第三方Web应用
-
最安全的方式
-
密码模式(Password)
- 适用场景:自家应用
-
用户直接提供密码
-
客户端模式(Client Credentials)
- 适用场景:服务间调用
-
无需用户授权
-
简化模式(Implicit)
- 适用场景:纯前端应用(不推荐)
OAuth流程示例(授权码模式)¶
1. 客户端 → 重定向到授权服务器
GET /oauth/authorize?client_id=xxx&redirect_uri=xxx&response_type=code
2. 用户 → 登录并授权
3. 授权服务器 → 返回授权码
Redirect: https://client.com/callback?code=AUTH_CODE
4. 客户端 → 使用授权码换取Token
POST /oauth/token
{
"grant_type": "authorization_code",
"code": "AUTH_CODE",
"client_id": "xxx",
"client_secret": "xxx"
}
5. 授权服务器 → 返回Token
{
"access_token": "...",
"refresh_token": "...",
"expires_in": 7200
}
🏢 多租户设计¶
租户隔离策略¶
- 数据库隔离
- 方案:每个租户独立数据库
- 优点:完全隔离,安全性高
-
缺点:成本高,维护复杂
-
Schema隔离
- 方案:共享数据库,独立Schema
- 优点:成本适中,隔离性好
-
缺点:数据库支持有限
-
字段隔离(推荐)
- 方案:所有表增加tenant_id字段
- 优点:成本低,易维护
- 缺点:需要严格的代码控制
租户上下文传递¶
// 通过ThreadLocal存储租户ID
public class TenantContext {
private static ThreadLocal<String> tenantId = new ThreadLocal<>();
public static void setTenantId(String id) {
tenantId.set(id);
}
public static String getTenantId() {
return tenantId.get();
}
public static void clear() {
tenantId.remove();
}
}
// MyBatis Plus拦截器自动添加租户条件
@Intercepts({@Signature(...)})
public class TenantInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) {
// 自动在SQL中添加 tenant_id = ?
}
}
📡 API设计规范¶
统一响应格式¶
错误码规范¶
| 范围 | 说明 |
|---|---|
| 2xx | 成功 |
| 4xx | 客户端错误 |
| 5xx | 服务端错误 |
| 1000-1999 | 认证相关错误 |
| 2000-2999 | 用户相关错误 |
| 3000-3999 | 权限相关错误 |
| 4000-4999 | 租户相关错误 |
接口版本控制¶
🔧 配置中心设计¶
配置分层¶
- 应用配置:application.yml(本地)
- 环境配置:Nacos配置中心(远程)
- 敏感配置:加密存储(密钥、密码)
配置热更新¶
支持以下配置的动态更新: - Token过期时间 - 安全策略(登录失败次数、锁定时间) - 缓存时间 - 限流阈值
📊 监控与日志¶
监控指标¶
- 业务指标
- 登录成功/失败率
- Token验证次数
- 在线用户数
-
API调用量
-
性能指标
- 接口响应时间
- 数据库查询时间
- Redis命中率
-
CPU/内存使用率
-
安全指标
- 异常登录次数
- Token被盗用次数
- 权限校验失败次数
日志规范¶
// 使用SLF4J统一日志
@Slf4j
public class AuthService {
public void login(String username) {
log.info("用户登录,username={}", username);
log.error("登录失败,原因:密码错误,username={}", username);
}
}
🚀 性能优化¶
优化策略¶
- 缓存优化
- 权限信息缓存,减少数据库查询
- 使用Redis Pipeline批量操作
-
布隆过滤器防止缓存穿透
-
数据库优化
- 合理的索引设计
- 读写分离
-
分页查询优化
-
代码优化
- 异步日志记录
- 线程池复用
-
避免N+1查询
-
网络优化
- HTTP/2
- GZIP压缩
- CDN加速
🔒 安全加固¶
安全措施¶
- 传输安全:强制HTTPS
- 存储安全:密码BCrypt加密
- 接口安全:限流、防重放
- 数据安全:敏感数据脱敏
- 审计安全:完整的审计日志