spring-cloud / spring-cloud-gateway

An API Gateway built on Spring Framework and Spring Boot providing routing and more.
http://cloud.spring.io
Apache License 2.0
4.51k stars 3.31k forks source link

FilterDefinition bug #2050

Closed fightingaman closed 3 years ago

fightingaman commented 3 years ago

Describe the bug version: springcloud:Greenwich.SR5 springboot:2.1.10.RELEASE

I used conditional parameters in the gateway for authentication, but a problem arose that the parameters were normal true and false in most cases for the same request. For example, out of 10W identical requests, 10 are problematic.

Sample I configured IgnoreAuth to be true, but with a small probability it's still false.

routes:
    - id: anchor1
       uri: lb://anchor
       predicates:
           - Path=/anchor/api/im/**
       filters:
           - IgnoreAuth=true

java code

@Configuration
@AutoConfigureBefore(GatewayAutoConfiguration.class)
@Slf4j
public class AuthGateWayFilterFactory extends AbstractGatewayFilterFactory<AuthGateWayFilterFactory.Config> {

    public AuthGateWayFilterFactory() {
        super(AuthGateWayFilterFactory.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enable");
    }

    @Override
    public GatewayFilter apply(Config config) {
        return new InnerFilter(config.enable);
    }

    private static class InnerFilter implements GatewayFilter, Ordered {
        private final boolean enable;

        public InnerFilter(boolean enable) {
            this.enable = enable;
        }

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            if (!enable) {
                ServerHttpRequest request = exchange.getRequest();
                HttpHeaders headers = request.getHeaders();
                List<String> list = headers.get("token");
                if (Objects.nonNull(list) && !list.isEmpty()) {
                    String token = list.get(0);
                    long ttl = JwtUtil.verfiyToken(token);
                    if (ttl > 1) {
                        String session = JwtUtil.getSession(token);
                        ServerHttpRequest newRequest = exchange.getRequest().mutate().headers(httpHeaders -> {
                            httpHeaders.add("session", session);
                        }).build();
                        ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
                        return chain.filter(newExchange);
                    }
                }
                Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
                String routeId = Objects.isNull(route) ? "" : route.getId();
                log.warn("Authentication failed,routeId:{},url:{}", routeId, request.getURI().toString());
                ServerHttpResponse response = exchange.getResponse();
                response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
                String json = JSON.toJSONString(Result.builder(CodeMsg.FAIL96));
                response.setStatusCode(HttpStatus.OK);
                DataBuffer buffer = response.bufferFactory().wrap(json.getBytes(StandardCharsets.UTF_8));
                return response.writeWith(Mono.just(buffer));
            }
            return chain.filter(exchange);
        }

        @Override
        public int getOrder() {
            return Ordered.HIGHEST_PRECEDENCE;
        }
    }

    @Override
    public String name() {
        return "IgnoreAuth";
    }

    @Data
    public static class Config {
        private boolean enable;
    }
spencergibb commented 3 years ago

I'm sorry, I don't understand. Har you saying that the value of Config.enable is sometimes not what you set it to be? If so, can you provide a complete, minimal, verifiable sample that reproduces the problem? You should also include steps to reproduce the issue. It should be available as a GitHub (or similar) project or attached to this issue as a zip file.

spring-cloud-issues commented 3 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-cloud-issues commented 3 years ago

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.