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

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

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

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

Всего 2 ответа


Да, есть 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 настраиваются в application.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.


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


Есть идеи?

10000