https 被redirect成了http

一、https 被redirect成了http

近期项目中踩到一个坑,记录下来,以免后面再踩。

背景:

目前mqrc项目并不是全站的https,而是仅在F5上配置了https,其架构大致下面这样(这里先省略架构中的apache):

.
                 浏览器
                  |
                  |(https)
            F5 (LoadBalance)               外网
   -----------------------------------------
            |      |      |                内网
            |(http)|(http)|(http) 
            |      |      |
            web   web    web
           应用1  应用2  应用3

也就是说https加密,仅限于浏览器到F5之间,而对web应用来说,所有的请求都是http的,这样如果应用中使用sendRedirect的请求,将会被转发到http。比如该项目中,在filter里的sendRedirect,原先的写法:

// 跳转到登陆页面         
httpServletResponse.sendRedirect(httpServletRequest.getContextPath()+"/login");

或者spring MVC中的写法:

//跳转到登录页面
    return "redirect:/login";

以上两种写法,当浏览器访问浏览器访问 https://intlapppdev.95516.com/portal/index 时,其实相当于发了两次请求,第二次浏览器会访问到 http://intlapppdev.95516.com/portal/login。

解决方案:

1. 跳转URL时使用绝对地址https(该方法不建议)

就是在filter中跳转地址前强制加上https,这种方法不够灵活,不建议使用

2. 使用forward方法

在servlet中使用RequestDispatcher的forward方法,它与sendRedirect的主要区别在于forward相当于一次请求,然后服务器端内部,以方法调用的方式转到目标地址。写法如下:

// 跳转到登陆页面         
RequestDispatcher view = servletRequest.getRequestDispatcher("/login");
view.forward(servletRequest,servletResponse);

不过使用forward方法,地址栏中看到的只有一个地址,比如https://intlapppdev.95516.com/portal/index,服务器返回了login.jsp页面,但浏览器地址栏没有改变。

3. 在响应信息中设置HTTP状态码和location头信息

进行URL重定向时,服务器设置HTTP状态码和location头信息,当状态码为302时,表明资源位置临时发生了改变,需要进行重定向,location头信息标识了资源转向的位置,该地址写相对地址。写法如下:

//跳转到登录页面
httpServletResponse.setStatus(302);//或者303,兼容http1.1
httpServletResponse.setHeader("location", httpServletRequest.getContextPath()+"/login");
4. spring mvc中,可以直接配置,将redirectHttp10Compatible属性设为false。如下:
<!-- redirectHttp10Compatible:解决https环境下使用redirect重定向地址变为http的协议,无法访问服务的问题,设置为false,即关闭了对http1.0协议的兼容支持
<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>

事实上,翻一翻spring底层的源码,可以看到,当redirectHttp10Compatible设为false的时候,处理方法也和上面3中提到的方法一致。设置了response头中的location和状态码。

4. 还有可以在Apache设置https反向代理,解决该问题。不过这不是应用层面的东西,这里不深究了

参考链接:

http://www.javatang.com/archives/2018/01/10/22132246.html#NginxX-Forwarded-Protohttp://rensanning.iteye.com/blog/2337766https://blog.csdn.net/YangFanJ/article/details/72236655

没有更多推荐了,返回首页