问题:
描述:一个springboot的http项目,公司使用nginx配置了ssl证书通过https访问,但是后台代码使用了redirect重定向,结果response返回都是http无法访问。
先贴一下nginx的配置
server {listen 8080 ssl;server_name 127.0.0.1;ssl_certificateserver.crt; #此配置文件和证书同一目录下ssl_certificate_key server.key; #此配置文件和证书同一目录下ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_session_timeout 5m;ssl_ciphersECDHE-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;@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {@Resourceprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns("/**");super.addInterceptors(registry);}}package com.xiaobai.interceptor;import org.ponent;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@Componentpublic class MyInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//重定向的地址response.sendRedirect("https://......");return super.preHandle(request, response, handler);}}
总结:亲测两种方式都可以解决问题,但是在实际使用过程中可能需要根据自己的业务需求做简单的调整,比如nginx的proxy_pass是否需要以“/”结尾;方案二中拦截的路径以及在什么条件下重定向等。
欢迎大家留言评论,提出问题,共同学习。