Можно ли запустить swagger и swagger-u SpringFox на другом порте, чем основное приложение? - PullRequest
0 голосов
/ 15 января 2020

Мы используем SpringBoot и SpringFox, используя @EnableSwagger2 для предоставления документации swagger-ui.html API (она нам не нужна для автоматизации клиентского кода, просто как документация и пользовательский интерфейс тестирования).

Возможно ли это запустить все связанные с Swagger конечные точки под другим портом (например, портом управления загрузочной пружиной / портом мониторинга), чем основное приложение?

Я немного исследовал, но не нашел пути в конфигурации swagger / springfox для сделай это. Есть ли весенний способ сделать это?

Ответы [ 2 ]

1 голос
/ 15 января 2020

Да, существует Spring способ сделать это:

Шаг 1. Добавление дополнительного соединителя Tomcat

Чтобы добавить порт для встроенного сервера, необходимо настроить дополнительный соединитель. Мы сделаем это, предоставив пользовательский WebServerFactoryCustomizer:

@Component
public class TomcatContainerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Value("${swagger.port}")
    private int swaggerPort;

    @Override
    public void customize(TomcatServletWebServerFactory factory) {

        Connector swaggerConnector = new Connector();
        swaggerConnector.setPort(swaggerPort);
        factory.addAdditionalTomcatConnectors(swaggerConnector);
    }
}

Теперь Tomcat прослушивает два порта, но обслуживает одинаковое содержимое на обоих из них. Нам нужно отфильтровать его.

Шаг 2. Добавление фильтра

Добавление фильтра сервлета довольно просто с FilterRegistrationBean. Его можно создать где угодно, я добавил его прямо в TomcatContainerCustomizer.

@Component
public class TomcatContainerCustomizer  implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Value("${swagger.port}")
    private int swaggerPort;

    @Value("${swagger.paths}")
    private List<String> swaggerPaths;

    @Override
    public void customize(TomcatServletWebServerFactory factory) {

        Connector swaggerConnector = new Connector();
        swaggerConnector.setPort(swaggerPort);
        factory.addAdditionalTomcatConnectors(swaggerConnector);
    }

    @Bean
    public FilterRegistrationBean<SwaggerFilter> swaggerFilterRegistrationBean() {

        FilterRegistrationBean<SwaggerFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new SwaggerFilter());
        filterRegistrationBean.setOrder(-100);
        filterRegistrationBean.setName("SwaggerFilter");

        return filterRegistrationBean;
    }

    private class SwaggerFilter extends OncePerRequestFilter {

        private AntPathMatcher pathMatcher = new AntPathMatcher();

        @Override
        protected void doFilterInternal(HttpServletRequest httpServletRequest,
                                        HttpServletResponse httpServletResponse,
                                        FilterChain filterChain) throws ServletException, IOException {

            boolean isSwaggerPath = swaggerPaths.stream()
                    .anyMatch(path -> pathMatcher.match(path, httpServletRequest.getServletPath()));
            boolean isSwaggerPort = httpServletRequest.getLocalPort() == swaggerPort;

            if(isSwaggerPath == isSwaggerPort) {
                filterChain.doFilter(httpServletRequest, httpServletResponse);
            } else {
                httpServletResponse.sendError(404);
            }
        }
    }
}

Свойства swagger.port и swagger.paths настраиваются в приложении. Yaml:

server.port: 8080
swagger:
  port: 8088
  paths: |
    /swagger-ui.html,
    /webjars/springfox-swagger-ui/**/*,
    /swagger-resources,
    /swagger-resources/**/*,
    /v2/api-docs

Итак пока все хорошо: swagger-ui обслуживается через порт 8088, наш API - на 8080. Но есть проблема: когда мы пытаемся подключиться к API от swagger-ui, запросы отправляются на 8088 вместо 8080.

Шаг 3. Настройка конфигурации SpringFox.

Swagger предполагает, что API работает на том же порту, что и Swagger-UI. Нам нужно явно указать порт:

@Value("${server.port}")
private int serverPort;

@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .host("localhost:" + serverPort);
}

И последняя проблема: поскольку пользовательский интерфейс работает на порте, отличном от API, запросы считаются перекрестными. Нам нужно разблокировать их. Это можно сделать глобально:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**/*").allowedOrigins("http://localhost:" + swaggerPort);
        }
    };
}

или добавив аннотации к контроллерам:

@CrossOrigin(origins = "http://localhost:${swagger.port}")

Используемые версии: SpringBoot 2.2.2.RELEASE, springfox-swagger2 2.9.2

Рабочий пример см. https://github.com/mafor/swagger-ui-port

0 голосов
/ 15 января 2020

Я так не думаю. Когда вы устанавливаете порт управления Spring Boot (management.server.port), запускается второй сервер приложений для обслуживания исполнительных механизмов. Насколько я знаю, нет никакой возможности (кроме пользовательских конечных точек привода) публиковать sh что-то на этом сервере.
Каков именно ваш вариант использования? Вы хотите запретить доступ к Swagger в рабочей среде или для пользователей, не прошедших проверку подлинности?

...