-
服务部署以及跳转展示如下:
-
用户https请求通过阿里云负载通过http到指定应用,应用返回跳转路径(状态为302),但跳转路径为http(不为https),所以访问不了
2.1 跳转伪代码:// ModelAndView mv.setViewName(WebCst.REDIRECT + "/admin/sso/login");
2.2 浏览器跳转截图
-
用nginx负载返回给浏览器的Location为https是因为nginx做了处理,关键配置见下
proxy_set_header Host $host; proxy_redirect http:// https://;
1.1 用arthas的trace命令观察线上,应用直接返回的Location为http://localhost:8232/exp-admin/admin/sso/login
watch org.apache.catalina.connector.Response toAbsolute -x 2
-
将nginx替换成SLB后,返回给浏览器的Loaction变为http是因为SLB缺少相应的配置
2.1 SLB相关配置:https://help.aliyun.com/document_detail/97646.html
-
后台是以springboot进行开发的,下面的分析都是基于springboot方式进行
-
先展示一下springmvc的工作原理
2.1 我们跳转设置为:mv.setViewName(WebCst.REDIRECT + “/admin/sso/login”); 结合上图,猜测根据视图进行跳转
2.2 视图解析器ContentNegotiatingViewResolver通过resolveViewName解析视图,得到跳转视图:RedirectView,调用其render进行跳转 -
以RedirectView#render进行跳转分析
3.1 下图显示以是否兼容http1.0(http10Compatible) 进行区分获取Location
(1)默认是兼容http1.0,故response.sendRedirect(encodedURL);
(2)response.sendRedirect(encodedURL)最终会触发到tomcat的org.apache.catalina.connector.Response的sendRedirect方法
public void sendRedirect(String location, int status) throws IOException { locationUri = toAbsolute(location); setStatus(status); setHeader("Location", locationUri); //设置跳转的location }
3.2 跳转Location生成的入口:org.apache.catalina.connector.Response#toAbsolute
// 从request中获取协议、IP、端口信息,然后和设置的相对路径拼接起来 protected String toAbsolute(String location) { String scheme = request.getScheme(); String name = request.getServerName(); int port = request.getServerPort(); redirectURLCC.append(scheme, 0, scheme.length()); redirectURLCC.append("://", 0, 3); redirectURLCC.append(name, 0, name.length()); if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443)) { redirectURLCC.append(':'); String portS = port + ""; redirectURLCC.append(portS, 0, portS.length()); } redirectURLCC.append(location, 0, location.length()); }
- 根据调用栈发现,在ConnectionHandler处理连接时,根据SocketEvent进行区别处理
- 在Http11Processor处理OPEN_READ事件时会对请求进行预处理
public SocketState service(SocketWrapperbase> socketWrapper) throws IOException { prepareRequestProtocol(); //设置为http1.1 prepareRequest(); //处理协议(http或者https) getAdapter().service(request, response); //调用后面Dispatcher }
- 在prepareRequest判断是否开启SSL,如果开启则为https
private void prepareRequest() throws IOException { if (protocol.isSSLEnabled()) { request.scheme().setString("https"); } }
- nginx官网对跳转描述:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect
- 设置在代理服务器响应的“Location” 头字段中更改的文本。
2.1 假设代理服务器返回头字段 “ Location: http://localhost:8000/two/some/uri/”。该指令proxy_redirect http://localhost:8000/two/ http://frontend/one/; 将此字符串重写为“ Location: http://frontend/one/some/uri/”。
2.2 在可以正常跳转的nginx上的配置为如下,将http转换成Httpsproxy_set_header Host $host; proxy_redirect http:// https://;
- 本地应用SSL配置:https://zhuanlan.zhihu.com/p/31385073
#https端口号. server.port: 443 #证书的路径. server.ssl.key-store: tomcat.keystore #证书密码,请修改为您自己证书的密码. server.ssl.key-store-password: 123456 #秘钥库类型 server.ssl.keyStoreType: PKCS12 #证书别名 server.ssl.keyAlias: tomcat
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)