Skip to content

安全认证

统一身份认证、服务间可信通信与全链路操作审计

完整测试代码参见https://gitee.com/javafree-cloud/javafree2025-examples


1. 架构概览:三位一体的企业级零信任安全基座

在微服务与云原生架构日益普及的背景下,传统边界防护模型已无法满足现代应用对细粒度访问控制、端到端可追溯性与自动化合规的要求。JavaFreeCloud 基于“永不信任,始终验证”(Never Trust, Always Verify)的零信任原则,构建了覆盖 身份认证层、服务通信层、操作审计层 的三位一体安全体系:

安全维度技术实现核心价值
统一身份认证JWT + RS256 双 Token 模型实现用户身份的无状态、标准化、高安全性管理
服务间可信通信HMAC-SHA256 对称签名机制保障微服务与第三方系统调用的完整性、防重放与来源可信
全链路操作审计异步日志采集 + 生命周期治理满足 GDPR、等保、金融行业等强合规场景的可追溯要求

该体系不仅提供开箱即用的安全能力,更通过配置驱动、模块解耦、扩展点开放的设计,支持企业按需定制安全策略,实现安全与敏捷的平衡。


2. JWT 统一身份认证系统:基于非对称加密的标准化身份治理

2.1 架构设计与安全优势

JavaFreeCloud 采用 Access Token + Refresh Token 双令牌架构,严格遵循 OAuth 2.0 最佳实践,并针对企业级场景进行深度优化:

  • Access Token(短期凭证)
    • 有效期:7200 秒(2 小时)
    • 签名算法:RS256(RSA-PKCS#1 v1.5 + SHA-256)
    • 存储建议:前端内存(如 Vuex/Pinia),避免持久化存储
    • 安全价值:短期有效大幅降低 Token 泄露后的攻击窗口;非对称签名确保即使公钥公开,也无法伪造 Token。
  • Refresh Token(长期凭证)
    • 有效期:86400 秒(1 天)
    • 存储建议:HttpOnly + Secure Cookie(防 XSS 与中间人窃取)
    • 体验价值:支持无感续签,用户无需频繁重新登录,提升产品可用性。

相较于对称签名(如 HS256)的优势

  • 私钥仅由认证中心(Auth Server)持有,资源服务器仅需公钥即可验签,密钥分发更安全
  • 支持多资源服务器并行验签,无密钥同步风险
  • 符合金融、政务等高安全等级场景的密钥隔离要求

2.2 密钥管理与部署实践

密钥通过内置工具 RsaKeyGenTool 生成,支持密码保护的 PKCS#8 格式私钥:

yaml
jwt:
  private.key: classpath:app.key        # 开发环境
  # private.key: /opt/certs/app.key     # 生产环境推荐
  public.key: classpath:app.pub
  private.key.password: "javafree-cloud-rsa-password"

🔐 生产环境密钥治理建议

  • 私钥文件应部署于受控目录(如 /opt/certs/),权限设为 600
  • 禁止将私钥打包进应用 Jar 包
  • 高安全场景可集成 HSM(硬件安全模块)或 HashiCorp Vault 进行密钥托管

2.3 自定义传输协议规避前端兼容性风险

为规避浏览器或代理对标准 Authorization Header 的自动大小写转换(如转为 authorization),框架采用自定义 Header 名称

yaml
jwt:
  token:
    token_name: Javafreeauthorization   # 全小写,避免前端自动格式化
    token_head: "Bearer "

此设计确保 Token 在跨域、反向代理、CDN 等复杂网络环境下仍能被正确解析,显著提升生产环境稳定性

2.4 精细化白名单与权限控制

通过 white_urls 显式声明免认证路径,遵循最小权限原则(Principle of Least Privilege):

yaml
jwt:
  security:
    white_urls:
      - /auth/token
      - /static/**
      - /actuator/health
      # 敏感路径如 /druid/** 应在生产环境移除

2.5 JWT 验证客户端示例:快速集成与调试

为便于开发与测试,框架提供了完整的 JWT 客户端工具类。以下为验证 Token 并提取用户信息的完整示例:

java
// 文件:TestJwtValidation.java
package cn.javafree.cloud.jwt.client;

import cn.javafree.cloud.jwt.client.config.JwtClientConfig;
import cn.javafree.cloud.jwt.client.utils.JwtUtils;

public class TestJwtValidation {
    private static final String JWT_TOKEN = "Bearer eyJhbGciOiJSUzI1NiJ9.xxxxx";

    public static void main(String[] args) {
        // 方式一:使用默认配置(从 classpath 加载公钥)
        testWithDefaultConfig();

        // 方式二:自定义配置(指定公钥路径)
        testWithCustomConfig();
    }

    private static void testWithDefaultConfig() {
        String token = JWT_TOKEN.startsWith("Bearer ") ? 
                       JWT_TOKEN.substring(7) : JWT_TOKEN;
        
        boolean valid = JwtUtils.isValid(token);
        if (valid) {
            JwtUserInfo userInfo = JwtUtils.getUserInfo(token);
            System.out.println("Realname: " + userInfo.getRealname());
            System.out.println("Email: " + userInfo.getEmail());
            // 支持 ID、Phone、WorkNo、UserType、Category 等扩展字段
        }
    }

    private static void testWithCustomConfig() {
        JwtClientConfig config = new JwtClientConfig();
        config.setPublicKeyPath("classpath:jwt/public-key.pem");
        JwtClient client = new JwtClient(config);
        
        boolean valid = client.isValid(token);
        JwtUserInfo userInfo = client.getJwtUserInfo(token); // 类型安全封装
    }
}

💡 客户端能力亮点

  • 自动剥离 Bearer 前缀,兼容标准与自定义传输格式
  • JwtUserInfo 提供类型安全的用户属性访问(ID、Realname、Email、Phone、WorkNo 等)
  • 支持动态公钥加载,适用于公钥轮换或远程获取场景
  • 内置过期检查、角色解析、调试日志等实用功能

3. HMAC 服务间安全调用机制:轻量级 API 网关替代方案

3.1 设计目标与适用场景

在 Service Mesh 尚未全面落地的中大型企业中,HMAC 签名提供了一种轻量、高效、无侵入的服务间认证方案,适用于:

  • 微服务 A → 微服务 B 的同步调用
  • 第三方系统回调(如支付、短信平台)
  • 后台批处理任务(ETL、定时同步)

其核心优势在于无状态、低延迟、高吞吐,无需维护会话或依赖中心化认证服务。

3.2 安全协议规范

客户端需按以下规则构造请求头(以 X-App- 为例):

Header说明安全作用
X-App-AccessKey调用方唯一标识身份识别,支持多租户
X-App-TimestampUnix 时间戳(秒)防重放(结合时间窗口)
X-App-Nonce16 字节随机字符串防重放(唯一性校验)
X-App-SignatureBase64(HMAC-SHA256(payload, secret))防篡改、来源认证

签名 payload 格式

{HTTP_METHOD}\n{REQUEST_PATH}\n{QUERY_OR_BODY}\n{TIMESTAMP}\n{NONCE}

HMAC-SHA256 的密码学优势

  • 抗碰撞性强,难以构造相同签名的不同请求
  • 计算效率高,适合高频调用场景
  • 服务端可通过 accessKey 动态查找对应 secret,支持多客户端密钥隔离

3.3 HMAC 客户端调用示例:标准 HTTP 集成

以下为使用 HmacAuthClient 发起带签名 GET 请求的完整测试代码:

java
// 文件:TestHmacAuthClient.java
package cn.javafree.cloud.jwt.client;

import cn.javafree.cloud.jwt.client.config.HmacAuthConfig;

public class TestHmacAuthClient {
    public static void main(String[] args) {
        // 1. 配置密钥(生产环境应从配置中心注入)
        HmacAuthConfig config = new HmacAuthConfig();
        config.setAccessKey("AK_30628108_837043_19C7");
        config.setSecret("2B3BF99C4618C76C53D96AAAD9CA7A388910810B225F2F373612C6CE1B3D5BA1");
        config.setHeaderPrefix("X-App-");

        // 2. 创建客户端
        HmacAuthClient client = new HmacAuthClient(config);

        // 3. 构造请求(GET 请求无 body)
        String path = "/sa-menu/getMenuById";
        String query = "id=108718494781401";
        Map<String, String> headers = client.buildHeaders("GET", path, query);

        // 4. 发送 HTTP 请求(使用 Java 11+ HttpClient)
        String fullUrl = "http://localhost:8090" + path + "?" + query;
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(fullUrl))
                .GET()
                .headers(headers.entrySet().stream()
                        .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
                        .toArray(String[]::new))
                .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
                .send(request, HttpResponse.BodyHandlers.ofString());

        System.out.println("Status: " + response.statusCode());
        System.out.println("Body: " + response.body());
    }
}

🛠️ 客户端设计亮点

  • 无依赖轻量级:仅依赖 JDK 11+ 标准库,无需额外 HTTP 客户端
  • 自动签名生成buildHeaders() 方法封装完整签名逻辑
  • 方法语义清晰:明确区分 GET(无 body)与 POST(含 body)的签名构造
  • 生产就绪:支持从环境变量或配置中心安全注入密钥

3.4 配置安全最佳实践

yaml
hmac:
  auth:
    auth-header-prefix: X-App-
    access-key: ${ACCESS_KEY}     # 从环境变量注入
    secret: ${HMAC_SECRET}        # 严禁硬编码

🛡️ 密钥生命周期管理建议

  • 通过配置中心(Nacos/Apollo)加密存储 secret
  • 定期轮换密钥(≤90 天),支持新旧密钥并行过渡
  • 为每个调用方分配独立密钥对,实现故障隔离与责任追溯

4. 登录日志全生命周期管理:满足强合规审计要求

4.1 审计内容与数据模型

系统自动记录每次认证尝试的关键元数据,形成结构化审计事件:

字段类型说明
usernameString用户账号
ip_addressString客户端真实 IP(支持 XFF 解析)
user_agentString设备与浏览器指纹
login_timeLocalDateTime精确到毫秒
resultEnumSUCCESS / FAILED(含失败原因)
tenant_idString多租户标识

该模型完全兼容 ISO/IEC 27001 A.12.4等保 2.0 “安全审计” 控制项

4.2 自动化清理与存储优化

yaml
accesslog:
  retention-minutes: 1440 # 日志保留多少分钟 默认 24 小时       # 可配置保留周期(默认 30 天)
  cleanup-cron: "0 0 2 * * ?"  # 每日凌晨 2 点执行
  • 动态可调:支持运行时调整保留策略,灵活应对 GDPR(≥6 个月)、金融行业(≥5 年)等不同合规要求
  • 低开销执行:基于 Spring Scheduler 的轻量级任务,不影响主业务性能
  • 归档友好:日志实体 SysLoginLog 支持无缝迁移至历史表或数据湖

5. 全链路访问日志审计:实现操作行为可追溯

5.1 日志采集策略

通过 AOP 切面自动拦截所有非白名单请求,采集关键上下文:

  • 请求方法、URI、参数(敏感字段可脱敏)
  • 用户身份(从 JWT 解析)
  • 客户端 IP、User-Agent
  • 响应状态码、处理耗时
  • 业务操作类型(通过注解扩展)

5.2 高性能异步写入架构

yaml
accesslog:
  storage: jpa               # 支持 JPA(关系型)或 Elasticsearch(分析型)
  thread-pool:
    core-size: 4
    max-size: 8
    queue-capacity: 1000     # 缓冲突发流量
  • 异步解耦:日志写入在独立线程池执行,零阻塞主业务流程
  • 智能过滤:自动排除静态资源(.js, .css)与监控端点(/actuator/**),减少 70%+ 无效日志
  • 资源保护:限制请求体缓存大小(默认 1MB),防止大文件上传导致 OOM

5.3 合规与运维价值

  • 安全事件回溯:快速定位异常操作(如批量删除、权限变更)
  • 性能瓶颈分析:结合耗时数据识别慢接口
  • 合规证据留存:满足 SOX、PCI DSS 等对“关键操作日志保留 ≥1 年”的要求

6. 安全体系核心优势总结

能力维度技术亮点业务价值
身份认证RS256 非对称签名 + 双 Token高安全性 + 无感续签体验
服务通信HMAC-SHA256 + 时间戳/Nonce轻量级、高吞吐、防重放
密钥管理配置中心集成 + 动态加载安全分发、便捷轮换
日志审计异步采集 + 生命周期治理合规就绪、运维提效
扩展性模块化设计 + 开放 SPI支持对接 SIEM、SOC 等安全平台

7. 总结:让企业级安全成为默认选项

JavaFreeCloud 安全体系并非简单功能堆砌,而是基于纵深防御(Defense in Depth)思想构建的有机整体:

  • 对外:通过标准化 JWT 协议,实现与前端、移动 App、第三方生态的无缝集成
  • 对内:通过 HMAC 签名,建立微服务间的可信通信通道
  • 对审计:通过全链路日志,构建“谁在何时做了什么”的完整证据链

开发者只需关注业务逻辑,安全细节由框架透明处理。这不仅大幅降低安全实施门槛,更确保安全策略在组织内一致、可靠、可持续地落地。

🔐 安全不是附加功能,而是架构基石 —— JavaFreeCloud 让企业级安全触手可及。


附录 A:安全配置参考(生产就绪)

JWT 配置 (jwt.yml)

yaml
jwt:
  private.key: /opt/certs/app.key          # 生产环境私钥路径
  public.key: https://auth.example.com/public-key  # 动态公钥(推荐)
  private.key.password: "${JWT_KEY_PASS}"  # 从环境变量读取
  token:
    token_name: Javafreeauthorization
    expiration: 7200
    refresh_expiration: 86400
  security:
    white_urls:
      - /auth/token
      - /auth/refresh_token
      - /actuator/health

HMAC 配置(服务提供方)

yaml
# HMAC 签名认证配置
# 用于服务端验证客户端请求的合法性(基于对称密钥的 API 签名机制)
# 客户端需使用相同的 accessKey、secret 和 headerPrefix 生成签名头
hmac:
  auth:
    # 认证请求头前缀,客户端和服务端必须一致
    # 例如:X-App- 表示头为 X-App-AccessKey, X-App-Signature 等
    auth-header-prefix: X-App-

HMAC 配置(服务调用方)

yaml
# HMAC 签名认证配置
# 用于服务端验证客户端请求的合法性(基于对称密钥的 API 签名机制)
# 客户端需使用相同的 accessKey、secret 和 headerPrefix 生成签名头
hmac:
  auth: 
    # 访问密钥(Access Key),用于标识调用方身份
    # 服务端可根据此 key 查找对应的 secret(支持多租户/多客户端场景)
    # 示例值: AK_30628108_837043_19C7
    access-key: your-access-key

    # 签名密钥(Secret Key),必须严格保密!
    # 用于生成和验证 HMAC-SHA256 签名,客户端与服务端必须一致
    # ⚠️ 切勿提交到代码仓库!建议通过环境变量或配置中心注入
    # 示例值: 2B3BF99C4618C76C53D96AAAD9CA7A388910810B225F2F373612C6CE1B3D5BA1
    secret: your-secret-key
    
    # HTTP 请求头前缀,所有认证相关头将以此开头
    # 客户端会发送如:X-Custom-AccessKey, X-Custom-Timestamp, X-Custom-Nonce, X-Custom-Signature
    # 默认值: X-App-
    # 修改后需确保客户端与服务端保持一致
    header-prefix: X-App-

日志策略

yaml
# 操作日志配置
accesslog:
  enabled: true # 是否开启日志存储 true or  false
  storage: jpa # 可选 jpa 或 elasticsearch
  retention-minutes: 1440 # 日志保留多少分钟 默认 24 小时
  cleanup-enabled: true
  cleanup-cron: "0 0 1 * * ?" # 默认每天凌晨 1 点执行 

  cache-request-body: false # 是否保存请求体, 为了控制是否记录请求体 默认为 false
  max-body-size: 1048576 # 超过这个值的字节数请求体,不缓存,默认 1M(1024*1024)

  # 要排除的 URL 路径(Ant 风格,多个用逗号分隔)
  exclude-paths: /actuator/**,/swagger-ui/**,/assets/**,/v3/api-docs/**,/webjars/**,/health

  # 要排除的静态资源后缀(多个用逗号分隔)
  exclude-suffixes: .js,.css,.png,.jpg,.jpeg,.gif,.ico,.woff,.woff2,.ttf,.svg,.eot,.map

   # 日志保存异步线程池配置
  thread-pool:
    core-size: 4
    max-size: 8
    queue-capacity: 1000
    keep-alive-seconds: 60
    thread-name-prefix: AccessLog-Async-
    await-termination-seconds: 30

附录 B:遵循的安全标准

  • 身份认证:OAuth 2.0 (RFC 6749), OpenID Connect Core 1.0
  • 令牌格式:JWT (RFC 7519), JWA (RFC 7518)
  • 加密算法:HMAC-SHA256 (FIPS 198-1), RSA-PKCS#1 v1.5
  • 合规框架:GDPR Article 30, 等保 2.0 三级要求, PCI DSS v4.0
  • 日志审计:ISO/IEC 27001:2022 A.8.16, NIST SP 800-92