Как включить только http на некоторых конечных точках и https на некоторых других конечных точках в контроллере spring boot rest?

#java #spring-boot #http #https #connector

#java #spring-boot #http #https #соединитель

Вопрос:

Я хочу включить http на некоторых конечных точках и https на другом наборе конечных точек.

Я получил такие решения, как настройка https через application.properties и http путем программного создания дополнительного соединителя, но все результаты включают как http, так и https для всех конечных точек.

Может кто-нибудь сообщить мне, как настроить некоторые конечные точки с помощью https и некоторые конечные точки с помощью http?

Комментарии:

1. найдено какое-либо решение?

2. Я тоже очень хочу знать. Кажется, вам нужно либо использовать все Http или Https, либо разрешить как http, так и https для всех конечных точек. Было бы неплохо настроить «разрешить http» только для определенных конечных точек, которые этого требуют, например */.well-known/acme-вызов для проверки домена LetsEncrypts.

Ответ №1:

Я понял это для сервлета Jetty, который я использую. Если вы используете сервлет TomCat по умолчанию, вам придется сделать что-то подобное, что работает для TomCat, я полагаю.

Итак, для начала у меня есть порт ssl по умолчанию, который активирован. Чтобы также разрешить http, вам необходимо настроить дополнительный порт http в вашей конфигурации. Затем вам нужно добавить обработчик сервера. Вы могли бы добавить обработчик SecuredRedirectHandler для перенаправления ВСЕХ http-запросов на порт https. Поскольку мы не хотим перенаправлять ВСЕ http-запросы, мы создаем наш собственный CustomRedirectHandler, который расширяет SecuredRedirectHandler.

 @Bean
public ConfigurableServletWebServerFactory webServerFactory() {
    JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
    factory.addServerCustomizers(new JettyServerCustomizer() {
        @Override
        public void customize(Server server) {
            final HttpConnectionFactory httpConnectionFactory = server.getConnectors()[0].getConnectionFactory(HttpConnectionFactory.class);
            // Enable HTTP for assigned port
            final ServerConnector httpConnector = new ServerConnector(server, httpConnectionFactory);
            httpConnector.setPort(serverProperties.intHttpPort() /* HTTP */);
            server.addConnector(httpConnector);
            // Add a CustomRedirectHandler to Server Handlers
            final HandlerList handlerList = new HandlerList();
            handlerList.addHandler(new CustomRedirectHandler());
            for(Handler handler : server.getHandlers()) {
                handlerList.addHandler(handler);
            }
            server.setHandler(handlerList);
        }
    });
    return factory;
}
  

В нашем CustomRedirectHandler мы можем проверить, находится ли запрошенная конечная точка в нашем массиве «разрешенный http». Если он уже запрашивает https или разрешен http, мы ничего не делаем, иначе перенаправляем на https. Мой пример разрешает http только для конечной точки, которая начинается с «/.well-known/acme-challenge/», чтобы разрешить запросы на http://example.com/.well-known/acme-challenge/TOKEN например.

 public class CustomRedirectHandler extends SecuredRedirectHandler {
    
    private final String[] allowedHttp = {"/.well-known/acme-challenge/"};
    
    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        HttpChannel channel = baseRequest.getHttpChannel();
        if (baseRequest.isSecure() || channel == null) {
            // nothing to do, already requested https
            return;
        }
        // Check if request is for allowed http
        if (allowHttp(baseRequest)) {
            return;
        }
        // Else Redirect to https
        super.handle(target, baseRequest, request, response);
    }

    public boolean allowHttp(Request baseRequest) {
        String pathInfo = baseRequest.getPathInfo();
        if (pathInfo == null) {
            return false;
        }
        for (String allowed : allowedHttp) {
            if (pathInfo.startsWith(allowed)) {
                return true;
            }
        }
        return false;
    }
    
    
}