LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

微服务Token鉴权的7种方案

freeflydom
2025年8月4日 8:50 本文热度 96

前言

最近有球友问我:微服务中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万用户余额,暴露三大漏洞:

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

2.常见的Token鉴权方案

方案1:基础JWT+Redis方案

该方案适合初创系统。

核心架构

致命陷阱

// 错误示例:未校验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种授权模式

授权码模式流程

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网关统一鉴权

该方案是微服务的标配。

架构设计

响应式鉴权过滤器

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如何传递

解决方案

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的核心区别

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认证

该方案是零信任架构。

工作流程

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消耗安全等级适用场景
基础JWT3ms15%★★☆内部微服务
OAuth2.035ms40%★★★☆第三方开放平台
Sa-Token5ms18%★★★快速开发项目
网关统一鉴权8ms25%★★★☆多语言混合架构
Token中继12ms30%★★★服务链调用
JWE加密45ms60%★★★★☆金融敏感数据
mTLS20ms50%★★★★★零信任网络

测试环境: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.方案如何选型?

总结

  1. 初创期:基础JWT+Redis方案
  2. 发展期:OAuth2.0+网关鉴权
  3. 成熟期:JWE加密+双向TLS
  4. 高级期:零信任架构+AI风控

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

转自https://www.cnblogs.com/12lisu/p/19017202


该文章在 2025/8/4 8:50:39 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved