一、现象

服务器上使用jar部署了一个springboot项目,现在要用https访问,所以用nginx配置ssl做了代理,配置好后,项目可以正常访问,但是点击退出,项目重定向后,https 就变成http导致项目报错

二、原因

spring mvc的servlet的secheme取值,request.getScheme()

是取请求里的一个scheme值,所有这个值在nginx代理时要设置成https

其中: request.getScheme() return http but not https.

三、处理

1、nginx配置

# 小程序端口
	server {
		listen       2043 ssl;
		server_name  bz.hhhtzxgzc.com;  # 替换为你的域名
		root html;
         index index.html index.htm;
		
		ssl_certificate      E:\\server\\nginx-1.26.2\\cert\\bz.hhhtzxgzc.com.pem;  # 证书文件路径
		ssl_certificate_key  E:\\server\\nginx-1.26.2\\cert\\bz.hhhtzxgzc.com.key;  # 私钥文件路径

		# 以下是一些SSL相关的配置参数,可根据需要调整
		ssl_session_timeout 5m;
		ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
		ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
		ssl_prefer_server_ciphers on;

		location / {
			# 将请求代理到 4080 端口
			proxy_pass http://127.0.0.1:4080;
			# 以下是一些常用的代理配置
			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;
			# 该指令会将后端响应header location内容中的http://替换成用户端协议https://。
			proxy_redirect   http:// https://;
		}
	}

重点是proxy_set_header Host $host:$server_port;  不然重合定向后,连端口都没了

原本以为 proxy_redirect   http:// https://; 设置后,nginx 会自动将http 转正https,测试后发现第一次访问还是会报错

再次回车后,才会转成https,当然有可能是我的nginx版本低了,如果哪个版本可以,小伙伴们可以留言告知

因为nginx配置没有彻底解决,我只能在springboot中修改代码

// 获取重定向的登录地址
public static String getRedirectUrl() {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if (attributes != null) {
			HttpServletRequest request = attributes.getRequest();
			String host = request.getHeader("X - Forwarded - Host");
			if (host == null) {
				host = request.getHeader("Host");
			}
			String scheme = request.getHeader("X - Forwarded - Proto");
			if (scheme == null) {
				scheme = request.getScheme();
			}

			if (host == null) {
				host = request.getServerName();
			}
			System.out.println("============================scheme="+scheme);
			System.out.println("================================host="+host);
			// 正对nginx https请求,重定向会将https://替换为http:// 这里做兼容,重新将http://替换为https://
            //固定哪个域名和端口,强制使用https 访问
			if("域名:端口".equals(host)){
				return scheme.replace("http","https") + "://" + host + "/shiro/toLogin";
			}
			return scheme + "://" + host + "/shiro/toLogin";
		}
		return "/shiro/toLogin";
	}
package com.hits.admin.fileter;

import com.hits.admin.config.RedisSessionDAO;
import com.hits.admin.constant.Constants;
import com.hits.admin.manager.AsyncManager;
import com.hits.admin.manager.factory.AsyncFactory;
import com.hits.admin.model.admin.SysUser;
import com.hits.admin.util.MessageUtils;
import com.hits.admin.util.RedisUtils;
import com.hits.admin.util.SpringUtils;
import com.hits.admin.util.UserUtils;
import com.hits.gzywxt.ywbl.gd.utils.exportUtil.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * @author 
 * @date 2021/11/13 0013
 */
public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter{
	private static final Logger log = LoggerFactory.getLogger(LogoutFilter.class);

	/**
	 * 退出后重定向的地址
	 */
	private String loginUrl;

	public String getLoginUrl()
	{
		return loginUrl;
	}

	public void setLoginUrl(String loginUrl)
	{
		this.loginUrl = loginUrl;
	}

	@Override
	protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception{
		try{
			Subject subject = this.getSubject(request, response);
			Session session = subject.getSession();
			String redirectUrl = UserUtils.getRedirectUrl();
			System.out.println("=============退出地址==========================="+redirectUrl);
			try{
				SysUser user = UserUtils.getCurrentUser();
				if (StringUtils.isNotNull(user)){
					String loginName = user.getLoginname();
					// 记录用户退出日志
					AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName,user.getJgbm(),Constants.LOGOUT, MessageUtils.message("user.logout.success")));
					// 清理缓存
					// SpringUtils.getBean(ISysUserOnlineService.class).removeUserCache(loginName, ShiroUtils.getSessionId());
					// 等保测评开启 避免越权访问
					// RedisUtils.hdel(Constants.PERMISSION_KEY, user.getLoginname() + "_" + SecurityUtils.getSubject().getSession().getId());
					System.out.println(user.getRealname() + "[" + user.getLoginname() + "]退出登录!");
					// 退出登录
					subject.logout();
					// 删除shiro session
					SpringUtils.getBean(RedisSessionDAO.class).delete(session);
				}
			}catch (SessionException ise){
				log.error("logout fail.", ise);
			}
			this.issueRedirect(request, response, redirectUrl);
		}catch (Exception e){
			log.error("Encountered session exception during logout.  This can generally safely be ignored.", e);
		}
		return false;
	}

	/**
	 * 退出跳转URL
	 */
	@Override
	protected String getRedirectUrl(ServletRequest request, ServletResponse response, Subject subject){
		String url = getLoginUrl();
		if (StringUtils.isNotEmpty(url)){
			return url;
		}
		return super.getRedirectUrl(request, response, subject);
	}


}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐