Why is https being redirected to http?

Site-wide HTTPS is not about configuring a certificate CA, it's as simple as changing the path URL!

SSL Offloading: Configure SSL on the load balancer, and then forward the decoded https data to the background web server after processing the handshake.
It is composed as follows:

            |
            |(https)
            |
         Load Balancer
      / | \
     / | \
    /(http) |(http) \(http)
WebServer1 WebServer2 WebServer3

The encrypted transmission of HTTPS will only be limited to the connection between the client-initiated request and the load balancer. In the public network stage, the communication on the intranet still uses unencrypted HTTP transmission. All processing requests in each web server are considered to be from http, and all sendredirects with relative paths will be forwarded to http!

For example, sendRedirect in Filter or Interceptor:
response.sendRedirect(request.getContextPath() + "/admin/welcome.do?flag=timeout");

Or "redirect:" in Spring's Controller:
return "redirect:/admin/welcome.do";


Through HttpServletResponseWrapper, SendRedirect requests can be intercepted through Filter and fixed to HTTPS.

web.xml
<filter>
  <filter-name>AbsoluteSendRedirectFilter</filter-name>
  <filter-class>com.rensanning.core.filter.AbsoluteSendRedirectFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>AbsoluteSendRedirectFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>


AbsoluteSendRedirectFilter.java
public class AbsoluteSendRedirectFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        RedirectResponseWrapper redirectResponseWrapper = new RedirectResponseWrapper(request, response);
        filterChain.doFilter(request, redirectResponseWrapper);
    }

}


RedirectResponseWrapper.java
public class RedirectResponseWrapper extends HttpServletResponseWrapper {

    private final HttpServletRequest request;

    public RedirectResponseWrapper(final HttpServletRequest inRequest, final HttpServletResponse response) {
        super(response);
        this.request = inRequest;
    }

    @Override
    public void sendRedirect(final String pLocation) throws IOException {

        if (StringUtils.isBlank(pLocation)) {
            super.sendRedirect(pLocation);
            return;
        }

        try {
            final URI uri = new URI (pLocation);
            if (uri.getScheme() != null) {
                super.sendRedirect(pLocation);
                return;
            }
        } catch (URISyntaxException ex) {
            super.sendRedirect(pLocation);
        }

        // !!! FIX Scheme  !!!
        String finalurl = "https://" + this.request.getServerName();
        if (request.getServerPort() != 80 && request.getServerPort() != 443) {
            finalurl += ":" + request.getServerPort();
        }
        finalurl + = pLocation;

        super.sendRedirect(finalurl);
    }

}


If you use Spring, you can set: redirectHttp10Compatible=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>


Reference:
http://www.exampit.com/blog/javahunter/5-8-2016-Why-does-https-become-http-on-a-sendredirect
http://stackoverflow.com/questions/3401113/spring -mvc-redirect-prefix-always-redirects-to-http-how-do-i-make-it-stay

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326589749&siteId=291194637