从单体到微服务:如何用Spring Authorization Server + JWT重构你的老系统登录模块

张开发
2026/4/6 10:10:49 15 分钟阅读

分享文章

从单体到微服务:如何用Spring Authorization Server + JWT重构你的老系统登录模块
从单体到微服务Spring Authorization Server JWT 重构登录模块实战指南当你的后台管理系统从单体架构迈向微服务时最棘手的挑战之一就是如何处理那些紧密耦合的登录和权限模块。传统的Session机制在分布式环境中显得笨重而低效而基于Token的认证方案则能完美适配微服务的无状态特性。本文将带你从零开始用Spring生态的最新工具完成这场关键转型。1. 为什么必须重构登录模块在单体应用时代我们习惯使用Session来管理用户状态——用户登录后服务器创建一个SessionID存入Cookie后续请求通过这个ID来识别用户。这套机制简单直接但随着系统拆分为多个微服务问题开始显现Session共享难题每个微服务都需要访问Session存储如Redis网络开销剧增跨域限制当服务部署在不同域名下时Cookie的携带变得复杂扩展瓶颈集中式Session存储成为单点故障源影响系统可用性// 传统Session验证示例单体架构 GetMapping(/profile) public String userProfile(HttpSession session) { User user (User) session.getAttribute(currentUser); if (user null) { return redirect:/login; } return profile; }而JWTJSON Web Token方案则彻底改变了游戏规则自包含性Token本身携带用户信息和权限服务端无需存储无状态验证各服务只需验证签名即可信任Token内容跨域友好通过HTTP Header传递不受同源策略限制2. 技术选型为什么是Spring Authorization ServerSpring生态提供了两种实现OAuth2的方案但选择很重要特性Spring Security OAuth2 (旧版)Spring Authorization Server (新版)维护状态停止更新官方主动维护规范支持OAuth2.0OAuth2.1 OpenID Connect 1.0配置方式注解驱动DSL配置JWT支持需要额外集成原生完善支持授权码模式增强基础实现PKCE支持选型建议新项目直接采用Spring Authorization Server它代表着未来方向。但如果你正在迁移旧系统需要评估兼容性成本。3. 迁移路线图四步走策略3.1 用户数据迁移与兼容设计首先确保用户体系能平滑过渡密码加密兼容如果旧系统使用MD5等弱加密需要逐步迁移到BCrypt权限模型映射将原有角色权限转换为JWT claims的标准格式双验证模式过渡期同时支持Session和Token验证-- 用户表新增字段示例 ALTER TABLE users ADD COLUMN jwt_secret VARCHAR(100) COMMENT JWT密钥版本号, ADD COLUMN migration_flag TINYINT DEFAULT 0 COMMENT 是否完成迁移;3.2 认证服务搭建实战使用Spring Authorization Server构建认证中心Configuration EnableAuthorizationServer public class AuthServerConfig { Bean public RegisteredClientRepository registeredClientRepository() { RegisteredClient client RegisteredClient.withId(UUID.randomUUID().toString()) .clientId(web-app) .clientSecret({bcrypt}$2a$10$...) .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN) .redirectUri(https://yourdomain.com/login/oauth2/code/web-app) .scope(read) .scope(write) .clientSettings(ClientSettings.builder() .requireAuthorizationConsent(false) .build()) .build(); return new InMemoryRegisteredClientRepository(client); } Bean public JwtDecoder jwtDecoder(JWKSourceSecurityContext jwkSource) { return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource); } Bean public JWKSourceSecurityContext jwkSource() { RSAKey rsaKey generateRsa(); JWKSet jwkSet new JWKSet(rsaKey); return (jwkSelector, securityContext) - jwkSelector.select(jwkSet); } }关键配置项说明密钥管理使用RSA非对称加密私钥签名、公钥验证令牌增强自定义JWT claims加入业务所需字段端点安全/oauth2/token等关键端点需要限流防护3.3 网关层统一鉴权API网关作为系统门户需要实现JWT验证检查签名、过期时间等基础属性权限预检根据路由规则进行粗粒度权限控制用户信息转发将解析后的claims传递给下游服务# 网关路由配置示例 spring: cloud: gateway: routes: - id: user-service uri: lb://user-service predicates: - Path/api/users/** filters: - TokenRelay - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 10 burstCapacity: 203.4 前端适配策略前端需要针对Token机制进行调整存储方案优先使用HttpOnly Cookie次选localStorage自动刷新当Token临近过期时静默刷新错误处理401错误跳转登录页403错误展示友好提示// Axios请求拦截器示例 axios.interceptors.request.use(config { const token store.getters.token; if (token) { config.headers[Authorization] Bearer ${token}; } return config; }); axios.interceptors.response.use(response { return response; }, error { if (error.response.status 401) { refreshToken().then(() { return axios.request(error.config); }); } return Promise.reject(error); });4. 进阶安全实践4.1 令牌生命周期管理虽然JWT是无状态的但仍需要一些有状态管理短期有效Access Token建议15-30分钟有效期刷新机制Refresh Token设置7天有效期并单次使用黑名单用户注销时将未过期的Token加入Redis黑名单// 令牌黑名单检查过滤器 public class JwtBlacklistFilter implements GatewayFilter { Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token extractToken(exchange.getRequest()); if (token ! null redisTemplate.hasKey(jwt:blacklist: token)) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } }4.2 密钥轮换方案定期更换签名密钥是必要安全措施双密钥机制新旧密钥同时有效一段时间服务端通知通过WebSocket或配置中心推送新密钥客户端适配自动重试获取新密钥后的请求# JWT Header示例包含密钥版本 { alg: RS256, kid: 2023-06-key // 密钥标识符 }4.3 监控与审计完善的监控体系包括令牌颁发日志记录IP、设备等上下文信息异常请求告警频繁的401/403错误需要关注权限变更追踪任何角色修改都应记录审计日志5. 灰度上线与回滚方案5.1 渐进式迁移策略按功能模块迁移先改造低风险的非核心模块用户分群发布内部用户→VIP用户→全体用户流量比例控制通过网关逐步切流5.2 回滚检查点设计准备三个关键回滚点数据库兼容版本保留旧用户表结构双认证模式开关配置切换Session/JWT验证前端降级方案保留Cookie处理逻辑# 功能开关配置示例 auth.modedual # 可选jwt/session/dual迁移过程中最常见的坑是忽略老接口的兼容性。我们曾遇到支付模块因为Token中缺少某个自定义claim而导致交易失败最终通过网关层字段补全解决了问题。建议在预发环境充分测试各边缘场景。

更多文章