版本 : v1.0
日期 : 2026-05-15
架构模式 : 单体架构(非微服务)
技术栈: Spring Boot 3.4+, Spring Security 6+, OAuth2.0 + OIDC
1. 系统概述
1.1 设计目标
本系统为商城平台提供统一的身份认证与授权解决方案,实现多客户端的单点登录 (SSO) 能力,采用业界标准的 OAuth2.0 授权码模式 + PKCE 增强安全机制,结合 OIDC 协议实现标准化身份认证。
1.2 业务场景覆盖
-
平台管理后台: 系统管理员 + 卖家角色权限管理
-
商城 C 端: 买家角色用户认证与授权
-
多客户端支持: Vue3 Web 管理后台、Vue3 商城前端
2. 系统整体架构图
数据层 (Data Layer)
Spring Boot 单体应用层
网关层 (Gateway Layer)
客户端层 (Client Layer)
HTTPS + PKCE
HTTPS + PKCE
路由转发
路由转发
路由转发
JDBC
JDBC
JDBC
JDBC
JDBC
vue3_web_platform_admin
Vue3 Web管理后台
vue3_web_mall
Vue3商城C端
Nginx 反向代理
端口: 80/443
oauth2_authorization_server
授权服务器
端口: 9000
oauth2_resource_server_admin_api
管理后台资源API
端口: 8080
oauth2_resource_server_buyer_api
买家端资源API
端口: 8081
MySQL - 授权数据库
ms_oauth2_auth
端口: 3306
MySQL - 管理后台数据库
ms_mall_admin
端口: 3307
MySQL - 商城数据库
ms_mall_buyer
端口: 3308
3. 数据流图 (Data Flow)
3.1 完整认证授权数据流
数据库 资源服务器 授权服务器 Vue3客户端 用户浏览器 数据库 资源服务器 授权服务器 Vue3客户端 用户浏览器 ========== 阶段1: 授权码请求 + PKCE ========== 参数: response_type=code client_id, redirect_uri code_challenge, code_challenge_method=S256 scope=openid profile offline_access ========== 阶段2: 令牌交换 ========== 参数: grant_type=authorization_code code, client_id, redirect_uri code_verifier (关键!) id_token (JWT-OIDC) access_token (JWT, 45分钟) refresh_token (不透明, 15天) ========== 阶段3: 资源访问 ========== Header: Authorization: Bearer {access_token} ========== 阶段4: 令牌刷新 ========== 参数: grant_type=refresh_token refresh_token, client_id 点击登录按钮 1. 生成 code_verifier (随机字符串64位) 2. 计算 code_challenge = SHA256(code_verifier) 3. 跳转授权端点 /oauth2/authorize 4. 验证客户端信息 5. 重定向到登录页面 6. 输入用户名密码提交 7. 查询用户信息验证 返回用户验证结果 8. 生成授权码 code (有效期5分钟) 9. 302重定向到 redirect_uri?code=xxx 10. POST /oauth2/token 11. 验证 code_verifier 匹配 验证通过 12. 生成令牌三元组 13. 持久化 refresh_token 14. 返回令牌响应 (JSON Body) 15. 请求API资源 16. JWT本地验签 (RSA公钥) 17. 解析权限声明 (scope/roles) 18. 业务数据查询 返回业务数据 19. 返回API响应 20. POST /oauth2/token (access_token过期前) 21. 验证 refresh_token 有效性 验证通过 22. 生成新的 access_token 23. 轮换 refresh_token (RTR策略) 24. 返回新令牌
4. 通讯架构图
渲染错误: Mermaid 渲染失败: Parse error on line 29: ...d B -->|1. 授权请求 (GET)| T T --> E ----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'
5. 令牌策略设计
5.1 令牌规格说明
| 令牌类型 | 格式 | 有效期 | 传输方式 | 存储位置 | 特性 |
|---|---|---|---|---|---|
| access_token | JWT (RS256 签名) | 45 分钟 | Authorization Header (Bearer) | 内存 / Vuex | 无状态、自包含、可本地验证 |
| refresh_token | 不透明随机字符串 | 15 天 | POST Request Body | HttpOnly Secure Cookie | 有状态、可吊销、支持轮换 |
| id_token | JWT (OIDC 标准) | 45 分钟 | JSON Body | 前端内存 | 身份断言、包含用户标准声明 |
5.2 安全约束
-
✅ 禁止通过 URL 参数传输任何令牌
-
✅ 所有 API 请求必须使用
Authorization: Bearer <token>头部 -
✅ refresh_token 仅通过 HTTPS POST 请求体传输
-
✅ 启用 Refresh Token Rotation (RTR) 策略
6. Spring Boot 应用端口分配表
| 应用名称 | 服务角色 | 端口 | 上下文路径 | 数据库连接 |
|---|---|---|---|---|
| oauth2_authorization_server | 统一授权服务器 | 9000 | / | ms_oauth2_auth:3306 |
| oauth2_resource_server_admin_api | 管理后台资源 API | 8080 | /api/admin | ms_oauth2_auth:3306 ms_mall_admin:3307 |
| oauth2_resource_server_buyer_api | 买家端资源 API | 8081 | /api/buyer | ms_oauth2_auth:3306 ms_mall_buyer:3308 |
6.1 本地开发环境访问地址
-
授权服务器: http://localhost:9000
-
管理 API: http://localhost:8080/api/admin
-
买家 API: http://localhost:8081/api/buyer
7. 数据库设计
7.1 数据库分布策略
| 数据库名称 | 端口 | 用途 | 核心表 |
|---|---|---|---|
| ms_oauth2_auth | 3306 | 授权中心数据库(共享) | 用户表、角色表、权限表、客户端表、授权表、令牌表 |
| ms_mall_admin | 3307 | 管理后台业务数据库 | 商品表、订单表、卖家表、系统配置表 |
| ms_mall_buyer | 3308 | 商城 C 端业务数据库 | 购物车表、收货地址表、买家订单表 |
设计说明: 授权数据独立存储,业务数据分库隔离,符合职责分离原则。三个数据库均运行在本地 MySQL 实例。
7.2 数据库表清单 (ms_ 前缀)
7.2.1 ms_oauth2_auth 数据库 (端口: 3306)
| 表名 | 说明 | 核心字段 |
|---|---|---|
| ms_user | 用户主表 | id, username, password, email, phone, enabled, account_non_expired, credentials_non_expired, account_non_locked |
| ms_role | 角色表 | id, role_code, role_name, description |
| ms_permission | 权限表 | id, permission_code, permission_name, resource_url, request_method |
| ms_user_role | 用户角色关联 | id, user_id, role_id |
| ms_role_permission | 角色权限关联 | id, role_id, permission_id |
| ms_oauth2_client | OAuth2 客户端注册 | id, client_id, client_secret, client_name, redirect_uris, scopes, authorization_grant_types, client_authentication_methods |
| ms_oauth2_authorization | 授权记录 | id, registered_client_id, principal_name, authorization_grant_type, attributes, state, authorization_code_value, authorization_code_issued_at, authorization_code_expires_at |
| ms_oauth2_authorization_consent | 用户授权同意 | id, registered_client_id, principal_name, authorities |
| ms_refresh_token | 刷新令牌存储 | id, token_value, user_id, client_id, issued_at, expires_at, revoked, revoked_at |
7.2.2 ms_mall_admin 数据库 (端口: 3307)
| 表名 | 说明 |
|---|---|
| ms_seller | 卖家信息表 |
| ms_product | 商品表 |
| ms_product_category | 商品分类表 |
| ms_order_admin | 订单管理表 |
| ms_system_config | 系统配置表 |
| ms_operation_log | 操作日志表 |
7.2.3 ms_mall_buyer 数据库 (端口: 3308)
| 表名 | 说明 |
|---|---|
| ms_buyer_profile | 买家个人资料 |
| ms_shopping_cart | 购物车表 |
| ms_receiving_address | 收货地址表 |
| ms_buyer_order | 买家订单表 |
| ms_user_favorite | 用户收藏表 |
8. 客户端配置差异对比
| 配置项 | vue3_web_platform_admin (管理后台) | vue3_web_mall (商城 C 端) |
|---|---|---|
| client_id | vue3-web-platform-admin | vue3-web-mall |
| client_authentication_method | none (公共客户端) | none (公共客户端) |
| authorization_grant_types | authorization_code, refresh_token | authorization_code, refresh_token |
| PKCE 强制 | ✅ 是 | ✅ 是 |
| redirect_uri | http://localhost:5173/callback | http://localhost:5174/callback |
| post_logout_redirect_uri | http://localhost:5173/login | http://localhost:5174/home |
| scope | openid profile offline_access admin:read admin:write | openid profile offline_access mall:read mall:write |
| 默认角色 | ROLE_ADMIN, ROLE_SELLER | ROLE_BUYER |
| access_token 有效期 | 30 分钟 | 60 分钟 |
| refresh_token 有效期 | 7 天 | 30 天 |
| 会话超时策略 | 严格超时 | 记住我功能 |
9. 可行性分析
9.1 技术可行性 ✅
| 评估维度 | 分析结论 | 说明 |
|---|---|---|
| 技术成熟度 | 高 | Spring Authorization Server 是官方标准实现,经过生产验证 |
| 标准兼容性 | 高 | 完全符合 OAuth2.0 RFC 6749、OIDC Core 1.0、PKCE RFC 7636 |
| 学习曲线 | 中 | Spring Security 配置较复杂,但社区文档完善 |
| 扩展性 | 高 | 支持后续扩展第三方登录(微信、支付宝) |
| 性能表现 | 高 | JWT 本地验签无远程调用,授权接口 QPS 支持 1000+ |
9.2 成本可行性 ✅
-
开发成本: 单体架构降低运维复杂度,开发周期约 2-3 人周
-
运维成本: 本地多 MySQL 实例,无需额外中间件(无 Redis)
-
许可成本: 全开源技术栈,无商业授权费用
9.3 安全可行性 ✅
-
纵深防御: PKCE + HTTPS + HttpOnly Cookie 多层防护
-
令牌安全: 短命 JWT + 可吊销 refresh_token + RTR 轮换策略
-
合规性: 符合等保 2.0 三级身份认证要求
9.4 风险评估与应对
| 风险点 | 影响等级 | 应对措施 |
|---|---|---|
| Spring Security 配置复杂 | 中 | 基于官方示例,编写详细配置文档 |
| JWT 令牌无法即时吊销 | 中 | 缩短 access_token 有效期,敏感操作二次校验 |
| 前端令牌存储安全 | 高 | refresh_token 使用 HttpOnly Secure Cookie |
10. Spring Security RBAC 权限设计
10.1 角色权限矩阵
渲染错误: Mermaid 渲染失败: Parse error on line 26: ...color:white```### 10.2 权限控制粒度- **URL ---------------------^ Expecting 'SEMI', 'NEWLINE', 'EOF', 'AMP', 'START_LINK', 'LINK', 'LINK_ID', got 'NUM'