前言
最近有球友问我:微服务中Token鉴权除了使用JWT之外,还有什么其他的方案?
今天这篇文章跟大家一起聊聊微服务Token鉴权的7种方案,希望对会有所帮助。
1. 为什么必须做Token鉴权?
传统Session的致命缺陷:

多个服务无法共享Session。
重复认证,导致系统性能严重下降。
2023年某电商平台发送安全事故:
GET /api/users/balance HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Gfx6VO9tcxwk6xqx9yYzSfebbeKDTHkQKh0xhu4nJE0
黑客通过XSS攻击窃取此Token后,在2小时内盗取5万用户余额,暴露三大漏洞:
- Token未绑定IP/设备指纹
- 敏感操作未二次认证
- 无异常行为检测机制
2.常见的Token鉴权方案
方案1:基础JWT+Redis方案
该方案适合初创系统。
核心架构:

致命陷阱:
public Claims parseJwt(String token) {
    return Jwts.parser() 
        .setSigningKey(SECRET_KEY)
        .parseClaimsJws(token)
        .getBody(); 
}
正确实现:
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种授权模式:

授权码模式流程:

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鉴权方案的精品。
三大核心优势:
- 一行代码实现登录鉴权
StpUtil.login(10001); 
@SaCheckPermission("user:delete")
public void deleteUser(Long id) {
  
}
- 内置会话管理
List<String> sessionList = StpUtil.searchSessionId("user:*", 0, 10);
- 踢人下线机制
StpUtil.kickout(10001);
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网关统一鉴权
该方案是微服务的标配。
架构设计:

响应式鉴权过滤器:
public class AuthFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        
        String token = extractToken(exchange.getRequest());
        
        
        return reactiveAuthService.validateToken(token)
                .flatMap(valid -> {
                    if (!valid) {
                        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                        return exchange.getResponse().setComplete();
                    }
                    return chain.filter(exchange);
                });
    }
}
性能优化技巧:
- 本地缓存:使用Caffeine缓存验证结果
- 批量验证:聚合10ms内请求统一鉴权
- 热点Token特殊处理
方案5:Token中继模式
该方案适合服务链调用。
核心问题:服务A调用服务B时Token如何传递
解决方案:

Feign中继实现:
@FeignClient(name = "service-b")
public interface ServiceBClient {
    
    @GetMapping("/data")
    Data getData(@RequestHeader("Authorization") String token);
}
public Data getData(String token) {
    
    return serviceBClient.getData("Bearer " + token); 
}
安全加固:使用JWT嵌套加密防止内部Token泄露
方案6:JWE加密令牌
该方案能保证金融级安全。
与JWT的核心区别:

Java生成示例:
public String createJwe(User user) throws JOSEException {
    
    JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.A256GCMKW, 
            EncryptionMethod.A256GCM).build();
    
    
    Payload payload = new Payload(new JSONObject()
        .put("sub", user.getId())
        .put("ssn", encrypt(user.getSsn()))); 
    
    
    JWEObject jwe = new JWEObject(header, payload);
    jwe.encrypt(new AESEncrypter(SECRET_KEY.getBytes()));
    
    return jwe.serialize();
}
适用场景:
方案7:双向TLS认证
该方案是零信任架构。
工作流程:

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;      
    private String userId;       
    private String operation;    
    private String resource;     
    private String clientIp;     
    private String deviceInfo;   
    private LocalDateTime time;  
}
5.方案如何选型?

总结
- 初创期:基础JWT+Redis方案
- 发展期:OAuth2.0+网关鉴权
- 成熟期:JWE加密+双向TLS
- 高级期:零信任架构+AI风控
微服务安全如同城堡防御——
单一的护城河无法阻挡所有入侵,
需要城墙、箭塔、卫兵的多层防护。
没有绝对安全的系统,只有不断提高的攻击成本。
转自https://www.cnblogs.com/12lisu/p/19017202
该文章在 2025/8/4 8:50:39 编辑过