【问题标题】:Spring Cloud Gateway: Set response status code in custom predicateSpring Cloud Gateway:在自定义谓词中设置响应状态码
【发布时间】:2021-12-26 13:20:16
【问题描述】:

在下面的代码 sn-p 中,我试图将我的请求与自定义谓词进行匹配。在谓词被评估为假后,我想发回一个自定义状态代码(下面的 sn-p 中的 403 禁止),而不是在谓词失败时发送的默认 404。这是我尝试过的。

路线定位器

@Bean
 public RouteLocator customRoutesLocator(RouteLocatorBuilder builder 
  AuthenticationRoutePredicateFactory arpf) {
    return builder.routes()
            .route("id1", r ->r.path("/app1/**")
                .uri("lb://id1")
                .predicate(arpf.apply(new Config()))).build();
}

AuthenticationRoutePredicateFactory

public class AuthenticationRoutePredicateFactory
    extends AbstractRoutePredicateFactory<AuthenticationRoutePredicateFactory.Config> {
public AuthenticationRoutePredicateFactory() {
    super(Config.class);
}

@Override
public Predicate<ServerWebExchange> apply(Config config) {

    return (ServerWebExchange t) -> {
        try {
             Boolean isRequestAuthenticated =  checkAuthenticated();

                return isRequestAuthenticated;
            }
        } catch (HttpClientErrorException e) {
           //This status code does not carried forward and 404 is displayed instead.
            t.getResponse().setStatusCode(HttpStatus.FORBIDDEN); 
            return false;
        }

    };

}

@Validated
public static class Config {

    public Config() {
    }
}

private Boolean checkAuthenticated() {
  // Some sample logic that makes a REST call and returns TRUE/FALSE/HttpClientErrorException
 //Not shown here for simplicity.
  return true;
}

}

当谓词返回为真时,请求被转发到 URI。但是,在显示错误评估 404 时,我需要显示 403(在 HttpClientErrorException 上)。这是期望带有自定义状态代码的响应的正确方法吗?此外,我还阅读了为给定路由实现自定义 webfilters 的内容,该路由可能会在转发请求之前修改响应对象。在这种情况下,有没有办法在谓词失败时调用过滤器?

【问题讨论】:

    标签: java spring-boot spring-cloud-gateway


    【解决方案1】:

    作为 Spring Cloud Gateway 的新手,我选择了错误的方向来解决这个问题。

    客户端向 Spring Cloud Gateway 发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关 Web 处理程序。谓词帮助网关处理程序映射确定该请求是否与路由匹配,并且只能返回 truefalse 值。

    一旦请求与路由匹配,处理程序通过特定于请求的过滤器链运行请求。这是在转发请求之前可以应用“pre”或“post”请求的地方。

    因此 为了在有条件地转发请求之前发送一个自定义的响应状态码,必须编写一个自定义的“pre”过滤器,这可以实现如下。 (设置403状态码)

    AuthenticationGatewayFilterFactory

      @Component
     public class AuthenticationGatewayFilterFactory
        extends AbstractGatewayFilterFactory<AuthenticationGatewayFilterFactory.Config> {
    
    
    public AuthenticationGatewayFilterFactory() {
        super(Config.class);
    }
    
    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            try {
                if(isRequestAuthenticated) {
                    return chain.filter(exchange);
                }
                else {
                    
                    exchange.getResponse().setStatusCode(403); // Any status code can be set here.
                    return exchange.getResponse().complete();
                }
                
    
            } catch (HttpClientErrorException e) {
                exchange.getResponse().setStatusCode(403); // Any status code can be set here.
                return exchange.getResponse().complete();
            }
    
        };
    }
    
    public static class Config {
    
    }
    
    private Boolean isRequestAuthenticated(String authToken) {
    
    // Some sample logic that makes a REST call and returns TRUE/FALSE/HttpClientErrorException
     //Not shown here for simplicity.
      return true;
    
    }
    

    路线定位器

     @Bean
     public RouteLocator customRoutesLocator(RouteLocatorBuilder builder 
      AuthenticationGatewayFilterFactory agff) {
        return builder.routes()
                .route("id1", r ->r.path("/app1/**")
                    .uri("lb://id1")
                    .filter(agff.apply(new Config()))).build();
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-29
      • 1970-01-01
      • 2016-11-21
      • 2020-04-30
      • 2020-12-15
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 2019-03-16
      相关资源
      最近更新 更多