同一 tomcat 不同项目 session 共享实现

说明

这里仅讨论 同一个tomcat,部署了两个工程(两个war包)。不涉及不同tomcat,不涉及集群

背景

tomcat中的工程A包含用户登录、退出、权限控制等功能;工程B包含业务功能接口。工程A将用户登录信息加密响应给前端,前端在请求工程B时将用户加密信息放入请求header,工程B解密获得用户信息。
这种方式在安全扫描中提示存在垂直越权问题。即低权限的用户如果拿到高权限用户的加密信息,就可以拿到高权限用户的数据

修复:

将用户信息存在session中

步骤1

服务器tomcat安装目录,conf文件夹下,sever.xml 文件标签新增配置

    <Host name="localhost"  appBase="webapps"  unpackWARs="true" autoDeploy="true">
              
                <Context path="/biz-m-rest" reloadable="true"  crossContext="true" sessionCookiePath="/" />

                <Context path="/mams-rest" reloadable="true" crossContext="true" sessionCookiePath="/" />

      </Host>

开启biz-m-rest、mams-rest服务session共享,sessionCookiePath=“/” 配置很重要,没有该配置 两个工程中打印的sessionId 不同

步骤2

工程A登录接口封装方法,将用户信息存入session中,sessionId 为key
网上很多博客用固定的key(session字符串),固定key虽然实现session共享,但是没有解决安全问题。本方法使用动态 sessionId 作为key

/*
*regUser参数为用户登录后,查询数据库封装的当前用户信息
*/
private void setUserInfoSissioin(SysRegisterUser regUser,HttpServletRequest request){
		HttpSession httpSession = request.getSession();
		String sessionId = httpSession.getId();
		logger.info("当前session id是=============:"+sessionId);
		Object jsonRegUser = JSON.toJSON(regUser);
		httpSession.setAttribute("user",jsonRegUser);
		ServletContext context = httpSession.getServletContext();
		context.setAttribute(sessionId, httpSession);
	}

步骤3

工程B中通过sessionId 获得用户信息

/*
	 *通过session 中保存的用户信息,和crctoken中解密的用户id 比较,相同返回true;否则返回false
	 *
	 */
	public Boolean isLoginUser(HttpServletRequest httpServletRequest){
		Boolean bool = false;
		String crcTokenUserId = getLoginUserId(); //cookie中解密的用户id(不安全)
		try {
			HttpServletRequest request = getRequest();
			String sessionId = request.getSession().getId();
			LOGGER.info("====biz_service session=====================start==="+sessionId);
			ServletContext Context = request.getServletContext();
			ServletContext Context1= Context.getContext("/mams-rest");  //共享session,和tomcat sever.xml 中配置一致

			if(Context1 !=null && !Context1.equals("")){
				HttpSession sess=(HttpSession)Context1.getAttribute(sessionId);
				if(sess.getAttribute("user")!=null){
					JSONObject jsonObject = new JSONObject().parseObject(sess.getAttribute("user").toString());
					String sessionUserId = jsonObject.getString("userId");  //session 中保存的用户id
					LOGGER.info("tomcat 共享session 测试=====================start====sessionUserId=002==="+sessionUserId);
					if(StringUtils.isNotBlank(sessionUserId)&&StringUtils.isNotBlank(crcTokenUserId)&&crcTokenUserId.equals(sessionUserId)){
						bool = true;
					}
				}
			}

		}catch (Exception e){
			//报错说明用户还没登录,拿不到session信息
			LOGGER.error("=============请先登录==========");
			e.printStackTrace();
		}

		return bool;
	}

测试:
工程A打印的sessionId
在这里插入图片描述
工程B打印的sessionId
在这里插入图片描述

动态获取工程A和工程B的sessionId,id相同,工程B才可以正确获取工程A中存的用户信息
保证工程A和工程B 有相同的sessionId 依赖 tomcat sever.xml中的配置
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值