问题:
描述:一个springboot的http项目,公司使用nginx配置了ssl证书通过https访问,但是后台代码使用了redirect重定向,结果response返回都是http无法访问。
先贴一下nginx的配置
server {
listen 8080 ssl;
server_name 127.0.0.1;
ssl_certificate server.crt; #此配置文件和证书同一目录下
ssl_certificate_key server.key; #此配置文件和证书同一目录下
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
#charset koi8-r;
#access_log logs/host.access.log main;
location /test { #test为服务名
proxy_pass http://127.0.0.1:8096/test;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# proxy_redirect http:// https://;
}
}
分析原因:使用https访问nginx通过nginx 的 proxy_pass到http的tomcat,也就是proxy_pass执行前request head的协议是https,而java redirect重定向主要是通过访问tomcat服务的请求head项来决定的,所有proxy_pass
执行后,tomcat结果返回response是http。
解决方案:
- 方案一:使用nginx的proxy_redirect修改response中的location中的协议http为https外网访问的协议。
- 方案二:代码自定义handler设置response.sendRedirect("https://........."),简单代码如下:
package com.xiaobai.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import javax.annotation.Resource; @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { @Resource private MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**"); super.addInterceptors(registry); } } package com.xiaobai.interceptor; import org.springframework.stereotype.Component; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component public class MyInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //重定向的地址 response.sendRedirect("https://......"); return super.preHandle(request, response, handler); } }
总结:亲测两种方式都可以解决问题,但是在实际使用过程中可能需要根据自己的业务需求做简单的调整,比如nginx的proxy_pass是否需要以“/”结尾;方案二中拦截的路径以及在什么条件下重定向等。
欢迎大家留言评论,提出问题,共同学习。