API 网关安全实践
一、引言
随着微服务架构的广泛普及,单体应用被拆分为数十甚至上百个微服务实例。每个微服务各自暴露接口,导致认证、授权、限流、日志审计等安全关注点分散在各服务中,难以统一管控。API 网关作为一种位于客户端与后端服务之间的中间层,承担着统一入口和安全集中管理的双重角色,成为微服务安全架构中不可或缺的关键组件。
本文围绕 API 网关的安全实践展开,首先阐述网关的安全角色定位,然后分别针对 Spring Cloud Gateway、Kong、APISIX 三款主流网关,介绍其核心安全配置与最佳实践,最后通过对比表和部署建议帮助读者在实际项目中做出合理选型与落地。
二、API 网关安全角色概述
2.1 统一入口
API 网关作为系统对外的唯一入口,所有外部请求必须先经过网关再路由到后端微服务。这种拓扑结构带来以下安全优势:
- 攻击面收敛:后端服务的真实地址对外不可见,外部攻击者无法直接针对具体服务发起攻击,必须绕过网关才能接触到服务接口,显著缩小了攻击面。
- 协议统一:网关可以统一处理 HTTPS 终止、协议转换(如 HTTP 转 gRPC),确保整个系统在传输层有一致的加密标准。
- 请求预处理:所有请求在到达业务服务之前,已在网关层完成合法性校验,无效或恶意请求被提前阻断,降低了后端服务的负载和安全风险。
2.2 安全集中管理
将安全能力集中到网关层,避免了在每个微服务中重复实现相同的安全逻辑,实现了安全策略的集中定义、统一执行、一致审计。典型的安全管理能力包括:
- 认证与授权:在网关层统一校验 JWT Token、OAuth2 令牌或 API Key,后端服务只需信任网关携带的安全上下文。
- 流量控制:集中配置限流、熔断和降级规则,防止突发流量冲垮后端服务。
- 审计日志:网关记录所有请求的访问日志,形成完整的审计轨迹,满足合规要求。
- 攻击防护:在网关层集成 WAF(Web 应用防火墙)、IP 黑/白名单、请求内容检查等防御机制。
三、Spring Cloud Gateway 安全实践
Spring Cloud Gateway 是 Spring 生态系统中的 API 网关实现,基于 Spring WebFlux 构建,天然适配 Spring Boot / Spring Cloud 微服务体系。以下介绍其核心安全配置方式。
3.1 路由安全配置
通过 RouteLocatorBuilder 或 YAML 配置文件定义路由规则时,可以为不同路由指定不同的安全过滤器链。
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
key-resolver: "#{@userKeyResolver}"
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
- id: admin-service
uri: lb://admin-service
predicates:
- Path=/api/admin/**
- RemoteAddr=10.0.0.0/8
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
key-resolver: "#{@adminKeyResolver}"
redis-rate-limiter.replenishRate: 50
redis-rate-limiter.burstCapacity: 1003.2 全局过滤器鉴权
通过实现 GlobalFilter 和 Ordered 接口,编写全局鉴权过滤器,对所有请求进行统一的 Token 校验。
@Component
@Order(-1)
public class AuthGlobalFilter implements GlobalFilter, Ordered {
private static final List<String> WHITE_LIST = Arrays.asList(
"/api/auth/login", "/api/auth/register", "/api/public/**"
);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
// 白名单路径直接放行
if (WHITE_LIST.stream().anyMatch(pattern -> pathMatch(pattern, path))) {
return chain.filter(exchange);
}
// 校验 JWT Token
String token = extractToken(exchange.getRequest());
if (token == null || !validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 将用户信息注入请求头,传递到下游服务
ServerHttpRequest mutatedRequest = exchange.getRequest().mutate()
.header("X-User-Id", getUserIdFromToken(token))
.header("X-User-Roles", getUserRolesFromToken(token))
.build();
return chain.filter(exchange.mutate().request(mutatedRequest).build());
}
}3.3 CORS 安全配置
跨域请求的安全控制是网关层的重要关注点。应使用白名单机制,仅允许受信任的来源访问。
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origins:
- "https://trusted-frontend.example.com"
- "https://admin.example.com"
allowed-methods:
- GET
- POST
- PUT
- DELETE
- OPTIONS
allowed-headers: "*"
allow-credentials: true
max-age: 3600安全建议:生产环境中不应使用 allowed-origins: "*",应明确列出受信任的域名;allow-credentials 为 true 时,allowed-origins 不能为 *,必须指定具体域名。
3.4 限流(RequestRateLimiter)
Spring Cloud Gateway 集成了基于 Redis 的令牌桶限流实现 RequestRateLimiterGatewayFilterFactory。通过自定义 KeyResolver,可以根据用户 ID、客户端 IP 等维度进行精细化限流。
@Bean
public KeyResolver userKeyResolver() {
return exchange -> {
String userId = exchange.getRequest().getHeaders()
.getFirst("X-User-Id");
if (userId != null) {
return Mono.just(userId);
}
return Mono.just(exchange.getRequest().getRemoteAddress()
.getAddress().getHostAddress());
};
}3.5 请求体检查
通过实现 GatewayFilter 或利用 ModifyRequestBodyGatewayFilterFactory,可以在网关层对请求体进行安全检查,例如校验 JSON 格式、检测 SQL 注入特征或敏感信息泄露。
public class RequestBodyCheckFilter implements GatewayFilter {
private static final Pattern SQL_PATTERN =
Pattern.compile("(?i)(select\\s.*from|insert\\s.*into|delete\\s.*from|union\\s.*select)");
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return ServerWebExchangeUtils.cacheRequestBody(exchange, (serverHttpRequest) -> {
return serverHttpRequest.getBody().next().map(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String body = new String(bytes, StandardCharsets.UTF_8);
if (SQL_PATTERN.matcher(body).find()) {
throw new SecurityException("请求体包含非法 SQL 关键字");
}
return bytes;
});
});
}
}3.6 AccessLog 审计
全局过滤器统一记录请求的访问日志,包含来源 IP、请求路径、方法、状态码、处理耗时等信息,为安全审计提供数据基础。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AccessLogFilter implements GlobalFilter {
private static final Logger log = LoggerFactory.getLogger(AccessLogFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long startTime = System.currentTimeMillis();
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
long duration = System.currentTimeMillis() - startTime;
log.info("AccessLog: {} {} {} {} {}ms",
request.getRemoteAddress(),
request.getMethod(),
request.getURI().getPath(),
response.getStatusCode(),
duration);
}));
}
}四、Kong 安全实践
Kong 是基于 Nginx 和 OpenResty 构建的高性能 API 网关,以其丰富的插件生态著称。安全相关的插件是其核心优势之一。
4.1 认证插件
Kong 提供了多种认证插件,支持不同的认证协议和场景。
Key-Auth(API 密钥认证)
# 为服务启用 Key-Auth 插件
curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=key-auth" \
--data "config.key_names=apikey" \
--data "config.hide_credentials=true"
# 创建消费者并绑定 API Key
curl -X POST http://localhost:8001/consumers \
--data "username=app-client"
curl -X POST http://localhost:8001/consumers/app-client/key-auth \
--data "key=sk-xxxxxxxxxxxx"JWT 认证
# 启用 JWT 插件
curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=jwt" \
--data "config.claims_to_verify=exp,nbf" \
--data "config.secret_is_base64=false"Kong 的 JWT 插件支持 RS256、HS256 等算法,推荐在生产环境中使用 RS256(非对称加密),确保密钥安全。
OAuth2 认证
Kong 的 OAuth2 插件实现了授权码流程(Authorization Code Grant),支持完整的 OAuth2 协议,适用于第三方应用授权场景。
4.2 速率限制插件(Rate Limiting)
Kong 的 Rate Limiting 插件支持本地和集群两种模式,可基于秒、分、小时、日、月等时间窗口进行限流。
curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=rate-limiting" \
--data "config.minute=100" \
--data "config.hour=5000" \
--data "config.policy=redis" \
--data "config.fault_tolerant=true" \
--data "config.redis_host=redis-cluster.example.com"配置要点:
policy=redis:集群模式下使用 Redis 存储计数器,确保多个 Kong 实例间的限流数据一致。fault_tolerant=true:当 Redis 不可用时,允许请求继续通过,避免限流组件故障导致服务完全不可用。- 支持按 Consumer、按 IP、按凭证等维度进行限流。
4.3 IP 限制
通过 IP Restriction 插件实现 IP 黑白名单控制。
# 仅允许内网 IP 访问管理接口
curl -X POST http://localhost:8001/services/admin-api/plugins \
--data "name=ip-restriction" \
--data "config.allow=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"4.4 ACL 插件
ACL(Access Control)插件与认证插件配合使用,实现基于角色的访问控制。
# 启用 ACL 插件
curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=acl" \
--data "config.allow=admin-group,editor-group" \
--data "config.hide_groups_header=true"
# 为消费者分配组
curl -X POST http://localhost:8001/consumers/app-user/acls \
--data "group=editor-group"4.5 请求转换
Kong 的 Request Transformer 插件可以在网关层修改请求头和请求体,用于安全上下文的注入。
curl -X POST http://localhost:8001/services/my-service/plugins \
--data "name=request-transformer" \
--data "config.add.headers=X-Forwarded-For:$remote_addr" \
--data "config.add.headers=X-Real-IP:$remote_addr" \
--data "config.remove.headers=X-Internal-Token"通过移除 X-Internal-Token 等敏感请求头,可以防止外部请求伪造内部身份。
五、APISIX 安全实践
Apache APISIX 是云原生高性能 API 网关,支持动态路由、热加载插件,在安全方面提供了丰富的认证和防护能力。
5.1 Consumer 认证
APISIX 通过 Consumer 概念管理调用方身份,支持多种认证插件。
Key-Auth 认证
# 创建 Consumer 并绑定 Key-Auth
consumers:
- username: service-a
plugins:
key-auth:
key: my-secret-key-123
# 在路由上启用 key-auth 插件
routes:
- uri: /api/v1/*
plugins:
key-auth:
header: X-API-Key
upstream_id: 1JWT 认证
routes:
- uri: /api/v2/*
plugins:
jwt-auth:
header: Authorization
algorithm: RS256
base64_secret: false
upstream_id: 2OIDC 认证
APISIX 支持 OpenID Connect 协议,可对接 Keycloak、Auth0、Okta 等身份提供商,实现单点登录(SSO)。
routes:
- uri: /oidc/callback
plugins:
openid-connect:
client_id: "api-gateway-client"
client_secret: "client-secret-value"
discovery: "https://auth.example.com/.well-known/openid-configuration"
bearer_only: false
scope: "openid profile email"
upstream_id: 15.2 限流与限并发
APISIX 提供了 limit-req(限制请求速率,基于漏桶算法)和 limit-count(限制请求计数,基于固定时间窗口)两个限流插件。
limit-req 配置示例:
plugins:
limit-req:
rate: 10 # 请求速率,每秒允许的请求数
burst: 20 # 突发流量大小
rejected_code: 429
key: "remote_addr" # 限流维度:客户端 IPlimit-count 配置示例:
plugins:
limit-count:
count: 1000 # 时间窗口内的请求限额
time_window: 60 # 时间窗口大小(秒)
rejected_code: 429
key: "remote_addr"
policy: redis # 集群模式下使用 Redis 共享计数器
redis_host: "10.0.0.10"
redis_port: 63795.3 IP 黑白名单
APISIX 的 ip-restriction 插件支持基于客户端 IP 的访问控制,同时支持 IPv4 和 IPv6。
plugins:
ip-restriction:
whitelist:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
blacklist:
- "1.2.3.4"
- "5.6.7.8/32"当同时配置黑名单和白名单时,白名单优先;匹配白名单的请求直接放行,匹配黑名单的请求被拒绝。
5.4 gRPC 代理安全
APISIX 原生支持 gRPC 代理(通过 grpc 或 grpcs 协议),在 gRPC 场景下同样可以应用认证、限流等安全插件。
routes:
- uri: "/helloworld.Greeter/SayHello"
plugins:
jwt-auth:
header: Authorization
limit-req:
rate: 100
burst: 200
key: "remote_addr"
upstream:
type: roundrobin
nodes:
"10.0.0.20:50051": 1通过 gRPC 网关层统一添加认证和限流,避免了在每个 gRPC 服务中重复实现安全逻辑。
5.5 WAF 插件
APISIX 提供了 waf 插件,集成 ModSecurity 核心规则集(CRS),在网关层拦截 SQL 注入、XSS、命令注入等常见 Web 攻击。
plugins:
waf:
mode: "allow" # allow: 仅记录不拦截 | block: 拦截并记录
rules: "/path/to/crs/rules"
audit_log: true # 记录攻击日志在部署 WAF 插件时,建议先在 allow 模式下运行一段时间,观察误报率,确认规则不会影响正常业务后再切换到 block 模式。
六、网关通用安全能力对比表
下表从多个安全维度对三款网关的核心能力进行横向对比。
| 安全能力 | Spring Cloud Gateway | Kong | APISIX |
|---|---|---|---|
| 认证方式 | 自定义 GlobalFilter 实现 | Key-Auth / JWT / OAuth2 / LDAP / HMAC | Key-Auth / JWT / OIDC / Basic-Auth / LDAP |
| 限流算法 | 令牌桶(基于 Redis) | 计数器 / 滑动窗口 | 漏桶(limit-req)/ 计数器(limit-count) |
| IP 黑白名单 | 通过 RemoteAddr 谓词实现 | ip-restriction 插件 | ip-restriction 插件 |
| ACL / RBAC | 自定义实现 | ACL 插件 + Consumer 分组 | consumer-restriction 插件 |
| CORS 安全 | 内置 globalcors 配置 | CORS 插件 | cors 插件 |
| WAF 能力 | 自定义过滤器实现 | 需集成第三方插件 | waf 插件(集成 ModSecurity) |
| gRPC 代理 | 不支持原生 gRPC | 通过插件扩展支持 | 原生支持 gRPC / gRPCS |
| 动态配置 | 需重启生效(静态路由) | 管理 API 动态生效 | Admin API 动态生效 |
| 性能基准 | 中等(基于 Reactor 模型) | 高(基于 Nginx / OpenResty) | 高(基于 Nginx / OpenResty) |
| 生态集成 | 原生 Spring Cloud 生态 | 企业版 + 丰富商业插件 | Apache 生态 + 开源社区活跃 |
七、安全网关部署最佳实践
7.1 网络架构安全
- DMZ 部署:将 API 网关部署在 DMZ(隔离区),后端服务部署在内部网络中,通过防火墙策略限制网关到后端服务的访问。网关服务器仅对外开放 443 端口(HTTPS)。
- 多层防御:网关前部署 CDN 和 DDoS 高防服务,过滤大流量攻击,网关层专注于协议层和应用层安全控制。不要将 WAF 作为唯一的防御层,应结合网络防火墙、主机安全等多层防护。
- TLS 终止:在网关层统一处理 HTTPS 证书的终止,后端服务之间使用内部 TLS 或明文通信(需在网络层面隔离)。推荐使用 TLS 1.3 协议,禁用不安全的 TLS 1.0 / 1.1 和弱密码套件。
7.2 密钥与凭证管理
- 外部化配置:所有认证密钥、API Key、数据库连接串等敏感信息不应硬编码在配置文件中,应通过环境变量、Kubernetes Secrets 或专业的密钥管理服务(如 HashiCorp Vault、AWS KMS)进行管理。
- 密钥轮换:制定密钥定期轮换策略。JWT 签名密钥至少每 90 天轮换一次,API Key 在发生泄露时应能立即吊销和更换。
- 最小化凭证传递:网关完成认证后,不应将原始凭证(如密码、API Key)传递到后端服务,应仅传递必要的安全上下文(用户 ID、角色、权限范围)。
7.3 日志与监控
- 全量审计日志:网关层记录所有请求的访问日志,至少包含以下字段:时间戳、来源 IP、请求方法、请求路径、响应状态码、处理耗时、用户标识。日志应集中存储,保留至少 180 天以满足合规要求。
- 异常告警:对以下异常行为设置告警阈值并通知安全团队——单一 IP 在短时间内大量 401 / 403 异常;限流触发次数突增;请求体包含攻击特征(SQL 注入、XSS 载荷);访问频率异常的非工作时间请求。
- 可观测性:部署 Metrics 指标暴露(请求量、错误率、P99 延迟),配合 Prometheus + Grafana 实现安全监控仪表板。
7.4 安全加固建议
- 最小化暴露:关闭网关的管理接口和调试端点,或将它们绑定到内网或管理 VLAN。Kong 的 Admin API(默认 8001 端口)不应暴露到公网,APISIX 的 Admin API 同理。
- 请求大小限制:限制请求体最大值,防止大 payload 攻击耗尽网关内存。Spring Cloud Gateway 通过
spring.codec.max-in-memory-size配置,Kong 通过nginx.http.client_max_body_size配置。 - 协议版本限制:仅允许使用 TLS 1.2 / 1.3,禁用 HTTP 明文访问。对所有 HTTP 请求 301 重定向到 HTTPS。
- 依赖安全:定期更新网关软件及其依赖组件,关注 CVE 漏洞公告,及时修补已知安全漏洞。
八、结语
API 网关是微服务安全架构的第一道防线,也是安全策略集中管控的最佳实践点。本文从 Spring Cloud Gateway、Kong、APISIX 三款主流网关入手,系统地介绍了路由安全、认证授权、限流防抖、WAF 防护等关键安全能力的配置方法,并通过对比分析和最佳实践建议,为读者在实际项目中选型、部署和运维安全网关提供了全面的参考。
无论选择哪款网关产品,安全都是一项持续性工作。网关层提供的是设施和策略,真正的安全效果取决于持续的监控、及时的补丁更新和完善的应急响应流程。建议团队在引入 API 网关后建立常态化安全运营机制,将网关日志接入安全信息与事件管理(SIEM)系统,形成闭环的安全防护体系。