You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Spring Gateway实现OAuth认证代理?

Spring Gateway统一处理OAuth2认证+暴露无验证内网端点实现方案

1. 核心依赖引入

首先在pom.xml中添加Spring Gateway、OAuth2客户端相关依赖:

<dependencies>
    <!-- Spring Gateway -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!-- OAuth2 Client -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
</dependencies>

2. OAuth2客户端与令牌配置

在application.yml中配置外部服务商的OAuth2参数,同时配置用于获取令牌的WebClient支持:

spring:
  security:
    oauth2:
      client:
        registration:
          external-service:
            client-id: YOUR_CLIENT_ID
            client-secret: YOUR_CLIENT_SECRET
            authorization-grant-type: client_credentials
            scope: api_access
        provider:
          external-service:
            token-uri: https://external-service.com/oauth2/token

spring:
  cloud:
    gateway:
      default-filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

3. 自定义GlobalFilter实现自动令牌注入

3.1 令牌缓存工具类

实现简单内存缓存避免重复请求令牌,生产环境可替换为分布式缓存:

@Component
public class TokenCache {
    private OAuth2AccessToken cachedToken;
    private final OAuth2AuthorizedClientManager authorizedClientManager;

    public TokenCache(OAuth2AuthorizedClientManager authorizedClientManager) {
        this.authorizedClientManager = authorizedClientManager;
    }

    public synchronized OAuth2AccessToken getValidToken() {
        if (cachedToken == null || cachedToken.isExpired()) {
            OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("external-service")
                    .principal("gateway-client")
                    .build();
            OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(authorizeRequest);
            cachedToken = authorizedClient.getAccessToken();
        }
        return cachedToken;
    }
}

3.2 全局过滤器实现

编写GlobalFilter,自动为转发到外部服务商的请求注入OAuth2令牌:

@Component
public class OAuth2TokenInjectFilter implements GlobalFilter, Ordered {
    private final TokenCache tokenCache;

    public OAuth2TokenInjectFilter(TokenCache tokenCache) {
        this.tokenCache = tokenCache;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 仅对目标代理路由生效,可根据实际路径规则调整
        if (exchange.getRequest().getPath().startsWithSegments("/external-api-proxy")) {
            OAuth2AccessToken token = tokenCache.getValidToken();
            ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
                    .header("Authorization", "Bearer " + token.getTokenValue())
                    .build();
            return chain.filter(exchange.mutate().request(modifiedRequest).build());
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        // 确保在路由转发前执行令牌注入
        return -100;
    }
}

4. 配置无验证端点与路由

4.1 路由规则配置

在application.yml中添加路由,将内网请求转发到外部服务商:

spring:
  cloud:
    gateway:
      routes:
        - id: external-service-proxy
          uri: https://external-service.com/api
          predicates:
            - Path=/external-api-proxy/**
          filters:
            - StripPrefix=1 # 去掉路径前缀/external-api-proxy

4.2 关闭内网端点安全验证

配置SecurityWebFilterChain,允许所有内网请求访问代理端点:

@Configuration
public class GatewaySecurityConfig {
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange(exchanges -> exchanges
                .anyExchange().permitAll() // 本次不做客户端身份校验
            )
            .csrf(csrf -> csrf.disable()); // 网关场景下通常关闭CSRF
        return http.build();
    }
}

关键说明

  • 若外部服务商采用其他授权类型,需调整authorization-grant-type及对应令牌获取逻辑
  • 后续切换自有认证体系时,仅需修改SecurityWebFilterChain添加客户端认证逻辑,令牌注入模块可复用

内容的提问来源于stack exchange,提问作者DGoiko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 11:11:24