200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 阿里云slb配置https重定向后变为http

阿里云slb配置https重定向后变为http

时间:2023-04-10 16:30:45

相关推荐

阿里云slb配置https重定向后变为http

阿里云slb配置https重定向后变http问题解决

背景描述问题部署结构 网上搜索到的方案方案一方案二 原理剖析Servlet容器重定向Shiro 重定向Spring MVC 重定向 总结最佳实践

背景描述

问题

阿里云slb配置443端口监听,然后将80端口的监听配置为重定向到https:443端口。

通过来访问站点,成功跳转至,实现了http强制跳https。

输入账号、密码登录系统,然后 “500”错误,F12浏览器debug发现提示以下错误:

Mixed Content: The page at '' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '/onLoginSuccess.html'. This request has been blocked; the content must be served over HTTPS.

部署结构

网上搜索到的方案

方案一

Spring MVC 里面使用到了redirect:/path,可以通过以下配置来搞定:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- redirectHttp10Compatible:解决https环境下使用redirect重定向地址变为http的协议,无法访问服务的问题,设置为false,即关闭了对http1.0协议的兼容支持--> <property name="redirectHttp10Compatible" value="false" /> </bean>

大概意思就是因为代码了做了对http1.0兼容,导致了重定向以后返回去的就是http了。

方案二

使用了shiro框架,里面有什么loginUrlsucessUrl之类的配置,这里也会利用redirect进行跳转,具体方案如下:

重写RedirectView类,将http10Compatible开关关闭;硬编码强制修改response Header里面的Location的值;

太复杂了,学不会呀!!!

原理剖析

Servlet容器重定向

Servlet容器Tomcat(tomcat-embed-8.5.31)里面的一个类:org.apache.catalina.connector.Response里面有这么一段代码:

/*** 如果有需要的话把一个相对地址转化为绝对地址(我自己乱翻译的)*/protected String toAbsolute(String location) {...boolean leadingSlash = location.startsWith("/");if (location.startsWith("//")) {// Add the schemeString scheme = request.getScheme();....} else if (leadingSlash || !UriUtil.hasScheme(location)) {String scheme = request.getScheme();...} else {//啥也不干 直接返回return (location);}}

意思就是,需要重定向的话,Location里面的地址的Scheme根据request来,两者保持一致。

Shiro 重定向

属性http10Compatible的值影响重定向的行为。

org.apache.shiro.web.util.RedirectView

protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String targetUrl, boolean http10Compatible) throws IOException {if (http10Compatible) {response.sendRedirect(response.encodeRedirectURL(targetUrl));} else {response.setStatus(303);response.setHeader("Location", response.encodeRedirectURL(targetUrl));}}

如果http10Compatible=true,就把重定向的targetUrl的组装工作交给了servlet 容器处理,容器肯定是按照Servlet规范做了。

如果http10Compatible=false,响应码是303,并且Location的值是一个相对地址。猜测是浏览器收到这个相对地址以后会自动拼接前面的http(s)://,然后发起重定向。

Spring MVC 重定向

Spring MVC 中控制对Http 1.0 是否兼容的标识位是redirectHttp10Compatible该属性在UrlBasedViewResolver视图解析器内。

生效的地方依然是RedirectView,类:org.springframework.web.servlet.view.RedirectView

相关代码:

protected void sendRedirect(HttpServletRequest request, HttpServletResponse response,String targetUrl, boolean http10Compatible) throws IOException {...//encodedURL /abc/tests/safa.htmlif (http10Compatible) {HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE);if (this.statusCode != null) {response.setStatus(this.statusCode.value());response.setHeader("Location", encodedURL);}else if (attributeStatusCode != null) {response.setStatus(attributeStatusCode.value());response.setHeader("Location", encodedURL);}else {// Send status code 302 by default.response.sendRedirect(encodedURL);}}else {HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl);//303response.setStatus(statusCode.value());response.setHeader("Location", encodedURL);}}

如果redirectHttp10Compatible=true,就把重定向的targetUrl的组装工作交给了servlet 容器处理,容器肯定是按照Servlet规范做了。

如果redirectHttp10Compatible=false,响应码是303,并且Location的值是一个相对地址。猜测是浏览器收到这个相对地址以后会自动拼接前面的http(s)://,然后发起重定向。

总结

到这里问题基本清楚了,来个总结吧。

结论很明显Http10Compatible兼容与否,其实跟Http、Https并没有关系,只是恰巧出现的303状态码,以及Location里面存放的不在是完整的跳转url,而是一个/开头的相对地址,协议的组装交给了浏览器处理。因此给大家了这种错觉,Https和Http的问题依然存在。

最佳实践

Tomcat有一个配置项:

public static class Tomcat {/*** Header that holds the incoming protocol, usually named "X-Forwarded-Proto".*/private String protocolHeader;}

当请求通过nginx代理或者阿里云SLB转发的时候通过配置将请求protocol放在X-Forwarded-ProtoHeader 里面。后端容器就会根据协议在生成redirect Location采用相应的协议。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。