Spring Gateway和Auth0:IllegalArgumentException:找不到名为TokenRelay的GatewayFilterFactory

iqxoj9l9  于 2023-08-02  发布在  Spring
关注(0)|答案(5)|浏览(157)

我试图构建一个Spring Web关,它正在获取JWT并将令牌发送到所有底层服务。为此,我使用以下依赖项:

<!-- Spring Boot Dependencies -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<!-- Spring Boot Dependencies -->

<!-- Spring Cloud Dependencies -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Spring Cloud Dependencies -->

字符串
我将应用程序配置为Auth0:

spring:
  cloud:
    gateway:
      routes:
        - id: my-service
          uri: http://localhost:8001/
          predicates:
            - Path=/comments
          filters:
            - TokenRelay=   #to send the token to the underlying service
            - RemoveRequestHeader=Cookie    #remove cookies since underlying services don't need them
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: #my issuer-uri
          audience: #my audience


我实现了受众验证器和jwt解码器,如here所述:

@Configuration
@ConditionalOnProperty(name = {"spring.security.oauth2.resourceserver.jwt.issuer-uri"})
public class AuthenticationOauth2Configuration {

    @Value("${spring.security.oauth2.resourceserver.jwt.audience}")
    private String audience;

    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuer;

    @Bean(name = "customJwtDecoder")
    public JwtDecoder getJwtDecoder() {
        final NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(issuer);
        final OAuth2TokenValidator<Jwt> audienceValidator = new JwtAudienceValidator(audience);
        final OAuth2TokenValidator<Jwt> issuer = JwtValidators.createDefaultWithIssuer(this.issuer);
        final OAuth2TokenValidator<Jwt> audience = new DelegatingOAuth2TokenValidator<>(issuer, audienceValidator);

        jwtDecoder.setJwtValidator(audience);

        return jwtDecoder;
    }
}

public class JwtAudienceValidator implements OAuth2TokenValidator<Jwt> {

    private final String audience;

    public JwtAudienceValidator(final String audience) {
        this.audience = audience;
    }

    @Override
    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        final OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null);

        if (jwt.getAudience().contains(audience)) {
            return OAuth2TokenValidatorResult.success();
        }

        return OAuth2TokenValidatorResult.failure(error);
    }
}


然而,当我启动网关服务im得到以下错误:

Caused by: reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name TokenRelay
Caused by: java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name TokenRelay


我真的找不到任何关于如何解决这个问题的资源。

ssgvzors

ssgvzors1#

你需要org.springframework. Boot :spring-boot-starter-oauth2-client,正如这里所说的。但我不认为你需要它,只要你使用资源服务器。Gateway将在没有任何配置的情况下将您的头转发到下游,因此您将能够在那里找到授权头。

bnlyeluc

bnlyeluc2#

为了让spring cloud gateway将token传递给下游服务并验证token,您需要以下依赖项:

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

字符串

lpwwtiir

lpwwtiir3#

我给予一个例子来说明爱德华·卡奇罗夫所说的:
依赖性:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>

字符串
service application.yml:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://<AUTH0_DOMAIN>/

auth0:
  audience: <AUTH0_API_AUDIENCE>


服务安全配置:

@Configuration
@EnableWebSecurity
public class Oauth2ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Value("${auth0.audience}")
    private String audience;

    @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
    private String issuer;

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2ResourceServer()
                .jwt();
    }

    @Bean
    public JwtDecoder jwtDecoder() {
        final NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(issuer);

        jwtDecoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(
                JwtValidators.createDefaultWithIssuer(issuer),
                new AudienceValidator(audience)));

        return jwtDecoder;
    }

    static class AudienceValidator implements OAuth2TokenValidator<Jwt> {
        private final String audience;

        public AudienceValidator(final String audience) {
            this.audience = audience;
        }

        public OAuth2TokenValidatorResult validate(final Jwt jwt) {
            if (jwt.getAudience().contains(audience)) {
                return OAuth2TokenValidatorResult.success();
            }

            return OAuth2TokenValidatorResult.failure(new OAuth2Error("invalid_token", "The required audience is missing", null));
        }
    }
}


网关应用程序.yml

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://<AUTH0_DOMAIN>/
  cloud:
    gateway:
      routes:
        - id: my-service
          uri: lb://MY-SERVICE
          predicates:
            - Path=/api
    loadbalancer:
      ribbon:
        enabled: false


网关安全配置:

@Configuration
@EnableWebFluxSecurity
public class Oauth2ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(final HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2ResourceServer()
                .jwt();
    }
}

0aydgbwb

0aydgbwb4#

我遇到了同样的问题,我需要一个OAuth2消费者充当客户端,并将传入令牌转发到传出的资源请求。
当我使用的是Spring Cloud Gateway嵌入式反向代理时,我可以要求它将OAuth2访问令牌转发到它正在代理的服务。因此,上面的SSO应用程序可以简单地像这样增强(使用TokenRelay Filter):

spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - TokenRelay=

字符串
要为SpringCloudGateway启用此功能,请添加以下依赖项

  • Boot :spring-boot-starter-oauth2-client
  • org.springframework.cloud:spring-cloud-starter-security。

我有这个pom.xml配置:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-webflux-core</artifactId>
            <version>${springdoc.openapi.webflux}</version>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-webflux-ui</artifactId>
            <version>${springdoc.openapi.webflux}</version>
        </dependency>
    </dependencies>

vulvrdjw

vulvrdjw5#

错误定位您的文件夹可能是此错误的另一个原因。确保您没有将过滤器放在com.yourcompany.yourproejct之外。

相关问题