Префикс Spring MVC «redirect:» всегда перенаправляет на http - как мне сделать так, чтобы он оставался на https? - PullRequest
49 голосов
/ 04 августа 2010

Я решил это сам, но я потратил так много времени на поиски такого простого решения, я подумал, что оно заслуживает того, чтобы быть задокументированным здесь.

У меня есть типичная установка Spring 3 MVC с InternalResourceViewResolver:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
  <property name="prefix" value="/" />
  <property name="suffix" value=".jsp" />
</bean>

У меня есть довольно простой метод обработчика в моем контроллере, но я упростил его еще больше для этого примера:

@RequestMapping("/groups")
public String selectGroup() {
    return "redirect:/";
}

Проблема в том, что если я перехожу на https://my.domain.com/groups, я получаю http://my.domain.com/ после перенаправления.(На самом деле мой балансировщик нагрузки перенаправляет все http-запросы на https, но это просто вызывает многократные оповещения браузера типа «Вы покидаете / входите в безопасное соединение» для людей, у которых такие оповещения включены.)

Таким образом, вопрос заключается в следующем: как получить пружину для перенаправления на https, когда используется исходный запрос?

Ответы [ 5 ]

51 голосов
/ 04 августа 2010

Краткий ответ: установите свойство redirectHttp10Compatible для InternalResourceViewResolver в значение false:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
  <property name="prefix" value="/" />
  <property name="suffix" value=".jsp" />
  <property name="redirectHttp10Compatible" value="false" />
</bean>

Вместо этого вы можете сделать это для каждого отдельного запроса, если ваш метод-обработчик вернет View вместо String, а сам создаст RedirectView и вызовете setHttp10Compatible(false).

(Оказывается, виновником является HttpServletResponse.sendRedirect, который RedirectView использует для перенаправлений, совместимых с HTTP 1.0, но не иначе. Я думаю, это означает, что это зависит от реализации вашего контейнера сервлета (?); Я наблюдал проблему в обоих Tomcat и Причал.)

33 голосов
/ 22 октября 2015

Spring Boot предоставляет это хорошее решение на основе конфигурации , если вы работаете за прокси-сервером, просто добавьте эти два свойства в ваш файл application.properties:

server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto

Это работает для меня, развертывая без изменений spring-boot-sample-web-ui на Elastic Beanstalk за балансировщиком нагрузки https. Без этих свойств перенаправление в строке 68 MessageController по умолчанию http и зависает.

Надеюсь, это поможет.

6 голосов
/ 04 июля 2011

Вы уверены?

Глядя на код, кажется, нет никакой разницы.Оба варианта вызывают response.encodeRedirectURL (targetUrl), см. Строку 388 RedirectView:

if (http10Compatible) {
    // Always send status code 302.
    response.sendRedirect(response.encodeRedirectURL(targetUrl));
}
else {
    HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl);
    response.setStatus(statusCode.value());
    response.setHeader("Location", response.encodeRedirectURL(targetUrl));
}

У меня была та же проблема, но она была вызвана установкой tomcat за загрузочным балансировщиком.Loadbalancer выполняет SSL-квитирование и переадресацию, чтобы установить простое http-соединение.

Решением было бы отправить специальный заголовок Http в ваш Loadbalancer, чтобы tomcat мог «доверять» этому соединению.Использование фильтра сервлетов должно установить флаг response.isSecure.Затем перезаписать RedirectView, чтобы увидеть, является ли response.isSecure, и правильно ли его обработать.

Я оставил это решение коротким, потому что не уверен, обрабатывает ли он вопрос.

4 голосов
/ 10 июля 2018

Что мне помогло, так это добавление в application.properties server.tomcat.use-relative-redirects=true

Итак, когда у вас есть:

public function redirect() {
  return "redirect:/"
}

Без server.tomcat.use-relative-redirects будет добавлен заголовок Location, например: http://my-host.com/. С server.tomcat.use-relative-redirects это будет выглядеть так: /. Так что это будет относительно текущей страницы с точки зрения браузера.

0 голосов
/ 16 января 2018

если вы используете springmvc, вы можете попробовать следующее:

modelAndView.setView(new RedirectView("redirect url path", true, false));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...