Reputation: 1855
I solved this myself, but I spent so long discovering such a simple solution, I figured it deserved to be documented here.
I have a typical Spring 3 MVC setup with an 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>
I have a pretty simple handler method in my controller, but I've simplified it even more for this example:
@RequestMapping("/groups")
public String selectGroup() {
return "redirect:/";
}
The problem is, if I browse to https://my.domain.com/groups
, I end up at http://my.domain.com/
after the redirect. (In actuality my load-balancer redirects all http requests to https, but this just causes multiple browser alerts of the type "You are leaving/entering a secure connection" for folks who have such alerts turned on.)
So the question is: how does one get spring to redirect to https when that's what the original request used?
Upvotes: 62
Views: 55548
Reputation: 9222
Are you sure?
Looking at the code it seems there is no difference. Both variants use the encoded url, see the sendRedirect
method in RedirectView:
String encodedURL = isRemoteHost(targetUrl) ? targetUrl : response.encodeRedirectURL(targetUrl);
if (http10Compatible) {
// Other if/else stuff depending on status code
// Send status code 302 by default.
response.sendRedirect(encodedURL);
}
else {
HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl);
response.setStatus(statusCode.value());
response.setHeader("Location", encodedURL);
}
I had the same problem, but it was triggered by setting up tomcat behind a loadbalancer. The loadbalancer does the SSL handshake and forwards to tomcat a plain http connection.
Solution would be to send a special Http Header in your Loadbalancer, so tomcat can "trust" this connection. Using a servlet filter should set response.isSecure flag. Then overwrite RedirectView to see if response.isSecure and handle it the right way.
I kept this solution short because i am not sure if it machtes the question.
Upvotes: 7
Reputation: 200
I was also facing same issue...When redirecting it goes to http instead of HTTPS , below changes done :
RedirectView redirect = new RedirectView("/xyz",true);
redirect.setExposeModelAttributes(false);
redirect.setHttp10Compatible(false);
mav = new ModelAndView(redirect);
Upvotes: 0
Reputation: 49
This started happening for us on Chrome 87 (https://blog.chromium.org/2020/08/protecting-google-chrome-users-from.html), for a quickfix to avoid the warning page in our springboot app we solve it by adding use-relative-redirects: true
in the application.yml
.
Upvotes: 0
Reputation: 874
Since Spring Boot 2.1 you have to add the following configuration to your application.properties
:
server.use-forward-headers=true
or application.yml
:
server:
use-forward-headers: true
Upvotes: 4
Reputation: 1
I add scheme="https"
in file server.xml for connector with port="80"
:
<Connector port="80" protocol="HTTP/1.1" URIEncoding="UTF-8"
connectionTimeout="20000" redirectPort="443" scheme="https" />
Upvotes: 0
Reputation: 2062
What worked for me is adding this to application.properties server.tomcat.use-relative-redirects=true
So when you have:
public function redirect() {
return "redirect:/"
}
Without the server.tomcat.use-relative-redirects
it will add a Location
header like: http://my-host.com/
.
With the server.tomcat.use-relative-redirects
it will look like: /
.
So it will be relative to the current page from browser perspective.
Upvotes: 11
Reputation: 1
if you use springmvc ,you can try the following:
modelAndView.setView(new RedirectView("redirect url path", true, false));
Upvotes: 0
Reputation: 1001
Spring Boot provides this nice configuration based solution to this if you're running behind a proxy server, simply add these two properties to your application.properties
file:
server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
This works for me deploying the otherwise unchanged spring-boot-sample-web-ui to Elastic Beanstalk behind an https load balancer. Without these properties the redirect on line 68 of the MessageController
defaults to http and hangs.
Hope this helps.
Upvotes: 43
Reputation: 1855
The short answer is, set the InternalResourceViewResolver's redirectHttp10Compatible property to 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>
You could do this on a per-request basis instead, by having your handler method return View instead of String, and creating the RedirectView yourself, and calling setHttp10Compatible(false)
.
(It turns out the culprit is HttpServletResponse.sendRedirect, which the RedirectView uses for HTTP 1.0 compatible redirects, but not otherwise. I guess this means it's dependent on your servlet container's implementation (?); I observed the problem in both Tomcat and Jetty.)
Upvotes: 59