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

如何为已集成Keycloak认证的Spring Cloud Gateway配置策略执行器?

嘿,我来帮你搞定这个细粒度授权的需求!结合你现有的Spring Cloud Gateway配置,咱们可以分步骤实现Keycloak Policy Enforcer,同时让后端微服务作为OAuth2资源服务器运行。下面是具体的实现方案:

一、准备必要的依赖

首先得给Gateway和微服务添加对应依赖:

Gateway端依赖

如果用Keycloak官方适配器方案,需要引入这些(以Maven为例):

<dependencies>
    <!-- Spring Cloud Gateway核心 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!-- Keycloak Reactive适配器 -->
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-spring-boot-starter</artifactId>
    </dependency>
    <!-- Keycloak Reactive Security适配 -->
    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-reactive-spring-security-adapter</artifactId>
    </dependency>
</dependencies>

后端微服务依赖

如果用Spring官方OAuth2资源服务器方案:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

如果用Keycloak适配器方案,引入keycloak-spring-boot-starter即可。

二、Spring Cloud Gateway端配置改造

咱们先基于你提供的Security Config,改造为集成Keycloak Policy Enforcer的版本:

1. 修改SecurityConfig代码

@EnableWebFluxSecurity
public class SecurityConfig {

    @Autowired
    private KeycloakReactiveAuthenticationManager keycloakReactiveAuthenticationManager;

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange()
                .anyExchange().authenticated()
                .and()
                // 集成Keycloak认证管理器
                .authenticationManager(keycloakReactiveAuthenticationManager)
                .securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
                // 支持OAuth2登录(如果需要前端跳转登录页)
                .oauth2Login()
                .and()
                .headers().frameOptions().mode(Mode.SAMEORIGIN)
                .and()
                .csrf().disable();

        // 启用Keycloak Policy Enforcer做细粒度授权
        http.apply(keycloakReactivePolicyEnforcer());

        return http.build();
    }

    @Bean
    public KeycloakReactivePolicyEnforcerConfigurer keycloakReactivePolicyEnforcer() {
        return new KeycloakReactivePolicyEnforcerConfigurer();
    }
}

2. 添加Keycloak与Policy Enforcer配置

在application.yml里配置Keycloak连接信息和授权规则:

keycloak:
  server-url: http://你的Keycloak地址:8080/auth
  realm: 你的Realm名称
  resource: gateway-client-id # 在Keycloak里创建的网关客户端ID
  credentials:
    secret: 你的网关客户端密钥 # Keycloak客户端里的Secret
  policy-enforcer:
    enforcement-mode: ENFORCING # 强制模式,不满足权限直接拦截
    paths:
      # 配置/api开头的请求对应Keycloak里的api资源
      - path: "/api/**"
        resource: "api-resource" # 要和Keycloak里创建的资源名称一致
        methods:
          - method: GET
            scopes: ["api:view"] # 对应Keycloak里的权限/范围
          - method: POST
            scopes: ["api:create"]

3. 配置Token Relay(转发令牌到微服务)

要让后端微服务能拿到用户令牌,需要在Gateway路由里添加TokenRelay过滤器:

spring:
  cloud:
    gateway:
      routes:
        - id: 你的微服务路由ID
          uri: lb://你的微服务服务名 # 服务发现方式
          predicates:
            - Path=/api/**
          filters:
            - TokenRelay= # 自动转发当前请求的OAuth2令牌
三、后端微服务作为OAuth2资源服务器配置

这里提供两种方案,选你顺手的就行:

方案1:Spring官方OAuth2资源服务器(推荐)

配置SecurityConfig

@EnableWebSecurity
public class ResourceServerConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                .anyRequest().authenticated()
                .and()
                // 启用JWT资源服务器
                .oauth2ResourceServer()
                .jwt();
        return http.build();
    }
}

配置application.yml

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://你的Keycloak地址:8080/auth/realms/你的Realm名称

方案2:Keycloak适配器方案

配置SecurityConfig(Servlet微服务示例)

@KeycloakConfiguration
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider provider = keycloakAuthenticationProvider();
        provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(provider);
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .anyRequest().authenticated();
    }
}

配置application.yml

keycloak:
  server-url: http://你的Keycloak地址:8080/auth
  realm: 你的Realm名称
  resource: 微服务客户端ID # Keycloak里为微服务创建的客户端
  credentials:
    secret: 微服务客户端密钥
  bearer-only: true # 只接受Bearer令牌,不处理登录跳转
四、Keycloak后台配置要点

最后别忘了在Keycloak里做这些配置:

  • 创建Realm、网关客户端、微服务客户端
  • 给网关客户端开启Authorization Enabled,并创建对应的资源(比如api-resource)、权限(比如api:view、api:create)
  • 创建策略(比如基于角色、用户组),把权限分配给对应的角色/用户
  • 确保网关客户端有uma_protection权限(在客户端的Scope里添加)

这样一来,Gateway就会负责认证和细粒度的授权检查,后端微服务只需要验证令牌的合法性即可~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 15:17:51