微服务Token鉴权的7种方案

SEO教程2025-08-01100
    正在检查是否收录...

前言

最近有球友问我:微服务中Token鉴权除了使用JWT之外,还有什么其他的方案?

今天这篇文章跟大家一起聊聊微服务Token鉴权的7种方案,希望对会有所帮助。

1. 为什么必须做Token鉴权?

传统Session的致命缺陷

image

多个服务无法共享Session。

重复认证,导致系统性能严重下降。

2023年某电商平台发送安全事故

GET /api/users/balance HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Gfx6VO9tcxwk6xqx9yYzSfebbeKDTHkQKh0xhu4nJE0 

黑客通过XSS攻击窃取此Token后,在

2小时内盗取5万用户余额

,暴露三大漏洞:

  1. Token未绑定IP/设备指纹
  2. 敏感操作未二次认证
  3. 无异常行为检测机制

2.常见的Token鉴权方案

方案1:基础JWT+Redis方案

该方案适合初创系统。

核心架构

image

致命陷阱

// 错误示例:未校验Token有效性 public Claims parseJwt(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); // 若Token被注销仍能解析通过! } 

正确实现

// 结合Redis校验Token状态 public boolean validateToken(String token, UserDetails details) { String username = extractUsername(token); String redisToken = redisTemplate.opsForValue().get("token:"+username); // 双重验证:签名有效且未注销 return (username.equals(details.getUsername()) && !isTokenExpired(token) && token.equals(redisToken); } 

适用场景

:用户量<100万的中小型系统

方案2:OAuth2.0授权框架

该方案是第三方接入的首选。

OAuth2.0包含了4种授权模式

image

授权码模式流程

image

Spring Boot配置示例

spring: security: oauth2: client: registration: github: client-id: ${GITHUB_CLIENT_ID} client-secret: ${GITHUB_SECRET} scope: user:email,read:user provider: github: token-uri: https://github.com/login/oauth/access_token user-info-uri: https://api.github.com/user 

关键点:

必须使用PKCE扩展

防止授权码截持攻击

方案3:Sa-Token轻量级框架

该方案是的国产Token鉴权方案的精品。

三大核心优势

  1. 一行代码实现登录鉴权
// 登录 StpUtil.login(10001); // 鉴权 @SaCheckPermission("user:delete") public void deleteUser(Long id) { // 业务代码 } 
  1. 内置会话管理
// 查询所有会话 List<String> sessionList = StpUtil.searchSessionId("user:*", 0, 10); 
  1. 踢人下线机制
// 根据账号ID踢人 StpUtil.kickout(10001); // 根据Token值踢人 StpUtil.kickoutByTokenValue("xxxx"); 

网关集成方案

@Bean public SaReactorFilter saReactorFilter() { return new SaReactorFilter() .addInclude("/**") .setAuth(obj -> { SaRouter.match("/user/**").check(r -> StpUtil.checkPermission("USER")); SaRouter.match("/admin/**").check(r -> StpUtil.checkPermission("ADMIN")); }); } 

性能实测:QPS 12,000(Redis集群模式)

方案4:API网关统一鉴权

该方案是微服务的标配。

架构设计

image

响应式鉴权过滤器

public class AuthFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1. 提取Token String token = extractToken(exchange.getRequest()); // 2. 响应式鉴权调用 return reactiveAuthService.validateToken(token) .flatMap(valid -> { if (!valid) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } return chain.filter(exchange); }); } } 

性能优化技巧

  1. 本地缓存:使用Caffeine缓存验证结果
  2. 批量验证:聚合10ms内请求统一鉴权
  3. 热点Token特殊处理

方案5:Token中继模式

该方案适合服务链调用。

核心问题

:服务A调用服务B时Token如何传递

解决方案

image

Feign中继实现

@FeignClient(name = "service-b") public interface ServiceBClient { @GetMapping("/data") Data getData(@RequestHeader("Authorization") String token); } // 调用方 public Data getData(String token) { // 原样传递Token return serviceBClient.getData("Bearer " + token); } 

安全加固

:使用JWT嵌套加密防止内部Token泄露

方案6:JWE加密令牌

该方案能保证金融级安全。

与JWT的核心区别

image

Java生成示例

public String createJwe(User user) throws JOSEException { // 1. 组装Header JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.A256GCMKW, EncryptionMethod.A256GCM).build(); // 2. 创建Payload Payload payload = new Payload(new JSONObject() .put("sub", user.getId()) .put("ssn", encrypt(user.getSsn()))); // 敏感信息加密 // 3. 加密Token JWEObject jwe = new JWEObject(header, payload); jwe.encrypt(new AESEncrypter(SECRET_KEY.getBytes())); return jwe.serialize(); } 

适用场景

  • 支付凭证
  • 身份证号传输
  • 医疗健康数据

方案7:双向TLS认证

该方案是零信任架构。

工作流程


image

Spring Boot配置

server: ssl: key-store: classpath:server-keystore.p12 key-store-password: changeit key-alias: server client-auth: need # 关键配置 trust-store: classpath:client-truststore.p12 trust-store-password: changeit 

适用场景

  • 服务网格内部通信
  • 银行核心系统
  • 政府机密数据交换

3.性能压测对比

方案 平均延时 CPU消耗 安全等级 适用场景
基础JWT 3ms 15% ★★☆ 内部微服务
OAuth2.0 35ms 40% ★★★☆ 第三方开放平台
Sa-Token 5ms 18% ★★★ 快速开发项目
网关统一鉴权 8ms 25% ★★★☆ 多语言混合架构
Token中继 12ms 30% ★★★ 服务链调用
JWE加密 45ms 60% ★★★★☆ 金融敏感数据
mTLS 20ms 50% ★★★★★ 零信任网络

测试环境:AWS c5.4xlarge 16核32GB × 3节点

4.安全攻防

4.1 四大攻击手段及防御

攻击类型

防御方案

代码实现

Token窃取 绑定设备指纹 StpUtil.getToken().setExtra("deviceId", fingerprint)
重放攻击 Nonce校验+时间戳 redis.opsForValue().setIfAbsent(nonce, "used", 5, TimeUnit.SECONDS)
越权访问 动态权限校验 @SaCheckPermission("#user.id")
Token破解 定期轮换签名密钥 Jwts.parserBuilder().setSigningKeyResolver(new KeyRotationResolver())

4.2 审计日志必备字段

为了保证系统的操作安全,我们需要增加审计日志表。

审计日志必备字段如下:

public class AuditLog { private String tokenId; // Token唯一标识 private String userId; // 用户ID private String operation; // 操作类型 private String resource; // 访问资源 private String clientIp; // 客户端IP private String deviceInfo; // 设备信息 private LocalDateTime time; // 操作时间 } 

5.方案如何选型?

image

总结

  1. 初创期

    :基础JWT+Redis方案
  2. 发展期

    :OAuth2.0+网关鉴权
  3. 成熟期

    :JWE加密+双向TLS
  4. 高级期

    :零信任架构+AI风控

微服务安全如同城堡防御——
单一的护城河无法阻挡所有入侵,
需要城墙、箭塔、卫兵的多层防护。
没有绝对安全的系统,只有不断提高的攻击成本。

最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。

本文收录于我的技术网站:http://www.susan.net.cn

评论

昵称
邮箱
主页