Spring Cloud Gateway передает бин пользовательскому фильтру - PullRequest
1 голос
/ 28 марта 2019

Мы пытаемся использовать Spring Cloud Gateway для настройки архитектуры на основе микросервиса.В настоящее время мы определили маршрут программно:

@ServletComponentScan
@SpringBootApplication
public class GatewayApplication {
    // to be passed to and used by custom filter
    @Autowired
    RestTemplate restTemplate;

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
        .route("status", r -> r
            .method(HttpMethod.GET)
            .and()
            .path("/status")
            .filters(f -> f.rewritePath("/status", "/v2/status")
                           .filter(new AuthorizationFilter(restTemplate).apply(new Config(""))))
            .uri("http://localhost:8081/"))
        .build();
    }
}

Выше было бы перенаправить входящий запрос /status через GET в другую конечную точку.Мы хотели бы применить пользовательский фильтр, который мы реализовали в AuthorizationFilter.Этот фильтр, как следует из названия, является еще одной микросервисной службой, которая будет разрешать или отклонять входящий запрос на основе учетных данных и разрешений.

В настоящее время шаблон, которому мы следуем, который работает, заключается в добавлении Spring * 1008.* в вышеприведенный класс шлюза, а затем передать это RestTemplate в конструктор фильтра.

Однако как это можно сделать, если мы хотим перейти к использованию файла YAML для определения всех маршрутов?Предположительно в обоих случаях Spring будет создавать новый фильтр для каждого входящего запроса.Но в случае YAML, как мы можем передать что-то в construtor?Если это невозможно, есть ли другой способ добавить RestTemplate или любой другой ресурс в пользовательский фильтр Spring Gateway?

1 Ответ

1 голос
/ 28 марта 2019

Вы можете зарегистрировать свой собственный GatewayFilterFactory.Это позволяет вам предоставить пользовательскую конфигурацию, и в этой конфигурации вы можете использовать SpEL для ссылки на бин.

Например:

@Component
public class AuthenticationGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthenticationGatewayFilterFactory.Config> {
    public AuthenticationGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // TODO: Implement
    }

    public static class Config {
        private RestTemplate restTemplate;

        // TODO: Getters + Setters
    }
}

Теперь вы можетеиспользуйте SpEL для правильной ссылки на компонент RestTemplate:

spring:
  cloud:
    gateway:
      routes:
        - id: status
          uri: http://localhost:8081/
          filters:
            - name: Authentication
              args:
                restTemplate: "#{@nameOfRestTemplateBean}"
          predicates:
            - Path=/status

Кроме того, вы можете добавить компонент RestTemplate в свой фильтр шлюза.Например:

@Component
public class AuthenticationGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthenticationGatewayFilterFactory.Config> {
    private RestTemplate restTemplate;

    public AuthenticationGatewayFilterFactory(RestTemplate restTemplate) {
        super(Config.class);
        this.restTemplate = restTemplate;
    }

    @Override
    public GatewayFilter apply(Config config) {
        // TODO: Implement
    }

    public static class Config {
        // TODO: Implement
    }
}

Код / конфигурация, необходимые для внедрения, менее сложны, но также усложняют, если вы когда-нибудь решите поместить AuthenticationGatewayFilterFactory в отдельную библиотеку, как «потребители»."этой библиотеки не будет иметь никакого контроля над тем, какие RestTemplate вводятся.

...