论坛首页 Java企业应用论坛

IFrame在Weblogic9.2下的请求session被覆盖丢失

浏览 5009 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-09-01   最后修改:2011-09-01

开源平台G4Studio开发的系统部署到tomat和weblogic10.3版本都很正常,session管理没出现问题。唯独weblogic9.2有问题。求大侠们指点:


首先说明一下
不是weblogic下iframe跨域session丢失的问题而是同一个域下,iframe发出的请求重新生了一个sessionid把原来的请求覆盖掉导致原session丢失的问题。如下图所示:第一个sessionid为点登录按钮产生的ID,第二个ID为登录后iframe的请求重新生成了一个sessionid

 



 

iframe代码如下:

 

html:"<iframe name='mainFrame'  src='index.ered?reqCode=preferencesInit' scrolling='auto' frameborder='0' width='100%' height='100%' ></iframe>"

 

尝试用url重写jsessionid的方法,但依然不起作用:

 

html:"<iframe name='mainFrame'  src='index.ered;jsessionid=${jsessionid}?reqCode=preferencesInit' scrolling='auto' frameborder='0' width='100%' height='100%' ></iframe>"

 

相关java代码如下:

 

    这是一个session容器,关键代码第12行

 

	/**
	 * 获取一个SessionContainer容器,如果为null则创建之
	 * 
	 * @param form
	 * @param obj
	 */
	public static SessionContainer getSessionContainer(
			HttpServletRequest request) {
		SessionContainer sessionContainer = (SessionContainer) request
				.getSession().getAttribute("SessionContainer");
		if (sessionContainer == null) {
			sessionContainer = new SessionContainer();
			HttpSession session = request.getSession(true);
			session.setAttribute("SessionContainer", sessionContainer);
		}
		return sessionContainer;
	}
 

 

    这是登录按钮,关键代码第64行

 

	/**
	 * 登陆身份验证
	 * 
	 * @param
	 * @return
	 */
	public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Cookie cookies[] = request.getCookies();
		Cookie cookie = cookies[0];
		String account = request.getParameter("account");
		String password = request.getParameter("password");
		password = G4Utils.encryptBasedDes(password);
		log.info("帐户[" + account + "]正尝试登陆系统...");
		Dto dto = new BaseDto();
		dto.put("account", account);
		Dto outDto = organizationService.getUserInfo(dto);
		UserInfoVo userInfo = (UserInfoVo) outDto.get("userInfo");
		Dto jsonDto = new BaseDto();
		if (G4Utils.isEmpty(userInfo)) {
			jsonDto.put("success", new Boolean(false));
			jsonDto.put("msg", "帐号输入错误,请重新输入!");
			jsonDto.put("errorType", "1");
			log.warn("帐户[" + account + "]登陆失败.(失败原因:不存在此帐户)");
			write(jsonDto.toJson(), response);
			return mapping.findForward("");
		}
		if (!password.equals(userInfo.getPassword())) {
			jsonDto.put("success", new Boolean(false));
			jsonDto.put("msg", "密码输入错误,请重新输入!");
			jsonDto.put("errorType", "2");
			log.warn(userInfo.getUsername() + "[" + userInfo.getAccount() + "]" + "登录系统失败(失败原因:密码输入错误)");
			write(jsonDto.toJson(), response);
			return mapping.findForward("");
		}
		String multiSession = WebUtils.getParamValue("MULTI_SESSION", request);
		if ("0".equals(multiSession)) {
			Integer sessions = (Integer) g4Reader.queryForObject("countHttpSessions", account);
			if (sessions.intValue() > 0) {
				jsonDto.put("success", new Boolean(false));
				jsonDto.put("msg", "此用户已经登录,系统不允许建立多个会话连接!");
				jsonDto.put("errorType", "3");
				log.warn(userInfo.getUsername() + "[" + userInfo.getAccount() + "]"
						+ "登录系统失败(失败原因:此用户已经登录,系统不允许建立多个会话连接)");
				write(jsonDto.toJson(), response);
				return mapping.findForward("");
			}
		}
		userInfo.setSessionID(request.getSession().getId());
		userInfo.setSessionCreatedTime(G4Utils.getCurrentTime());
		userInfo.setLoginIP(request.getRemoteAddr());
		userInfo.setExplorer(G4Utils.getClientExplorerType(request));
		if (!checkMultiUser(userInfo, request)) {
			jsonDto.put("success", new Boolean(false));
			jsonDto.put("msg", "不允许在同一客户端上同时以不同帐户登录系统,请先退出你已经登录的帐户后再尝试登录!");
			jsonDto.put("errorType", "1");
			log.warn("帐户[" + account + "]登陆失败.(失败原因:不允许在同一客户端上同时以不同帐户登录系统.请先退出你已经登录的帐户后再尝试登录)");
			write(jsonDto.toJson(), response);
			return mapping.findForward("");
		}
		getSessionContainer(request).setUserInfo(userInfo);
		log.info(userInfo.getUsername() + "[" + userInfo.getAccount() + "]" + "成功登录系统!创建了一个有效Session连接,会话ID:["
				+ request.getSession().getId() + "]" + G4Utils.getCurrentTime());
		SessionListener.addSession(request.getSession(), userInfo); // 保存有效Session
		if (pHelper.getValue("requestMonitor", "0").equals("1")) {
			saveLoginEvent(userInfo, request);
		}
		jsonDto.put("success", new Boolean(true));
		jsonDto.put("userid", userInfo.getUserid());
		write(jsonDto.toJson(), response);
		return mapping.findForward("");
	}
 

    这是过滤器,关键代码第11-13行

	/**
	 * 过滤处理
	 */
	public void doFilter(ServletRequest pRequest, ServletResponse pResponse, FilterChain fc) throws IOException,
			ServletException {
		HttpServletRequest request = (HttpServletRequest) pRequest;
		HttpServletResponse response = (HttpServletResponse) pResponse;
		String ctxPath = request.getContextPath();
		String requestUri = request.getRequestURI();
		String uri = requestUri.substring(ctxPath.length());
		UserInfoVo userInfo = WebUtils.getSessionContainer(request).getUserInfo();
		System.out.println(requestUri + "?reqCode=" + request.getParameter("reqCode"));
		System.out.println("new:" + request.getSession().getId());
		BigDecimal costTime = null;
		PropertiesHelper pHelper = PropertiesFactory.getPropertiesHelper(PropertiesFile.G4);
		String eventMonitorEnabel = pHelper.getValue("requestMonitor", "1");
		String postType = request.getParameter("postType");
		postType = G4Utils.isEmpty(postType) ? G4Constants.PostType_Normal : postType;
		if (postType.equals(G4Constants.PostType_Nude)) {
			long start = System.currentTimeMillis();
			fc.doFilter(request, response);
			if (eventMonitorEnabel.equalsIgnoreCase(ArmConstants.EVENTMONITOR_ENABLE_Y)) {
				costTime = new BigDecimal(System.currentTimeMillis() - start);
				saveEvent(request, costTime);
			}
		} else {
			String isAjax = request.getHeader("x-requested-with");
			if (G4Utils.isEmpty(userInfo) && !uri.equals("/login.ered") && enabled) {
				if (G4Utils.isEmpty(isAjax)) {
					response.getWriter().write(
							"<script type=\"text/javascript\">parent.location.href='" + ctxPath
									+ "/login.ered?reqCode=init'</script>");
					response.getWriter().flush();
					response.getWriter().close();
				} else {
					response.sendError(G4Constants.Ajax_Timeout);
				}
				log.warn("警告:非法的URL请求已被成功拦截,请求已被强制重定向到了登录页面.访问来源IP锁定:" + request.getRemoteAddr() + " 试图访问的URL:"
						+ request.getRequestURL().toString() + "?reqCode=" + request.getParameter("reqCode"));
				return;
			}
			if (G4Utils.isNotEmpty(isAjax) && !uri.equals("/login.ered")) {
				if (!request.getParameter("loginuserid").equals(userInfo.getUserid())) {
					response.sendError(G4Constants.Ajax_Session_Unavaliable);
					log.error("当前会话和登录用户会话不一致,请求被重定向到了登录页面");
					return;
				}
			}
			// if(){.... return;}
			long start = System.currentTimeMillis();
			fc.doFilter(request, response);
			if (eventMonitorEnabel.equalsIgnoreCase(ArmConstants.EVENTMONITOR_ENABLE_Y)) {
				costTime = new BigDecimal(System.currentTimeMillis() - start);
				saveEvent(request, costTime);
			}
		}
	}
  • 大小: 156.6 KB
   发表时间:2011-09-01  
url:/G4/login.ered?reqCode=login&jsessionid=null
jsessionid:tS1JTfPcFQcG3X5HQ2cSZDGGRvWLm2M11GBXssZ0SnyLRCCJwQhd!-680202136!1314852700525
url:/G4/index.ered?reqCode=indexInit&jsessionid=null
jsessionid:tS1JTfPcFQcG3X5HQ2cSZDGGRvWLm2M11GBXssZ0SnyLRCCJwQhd!-680202136!1314852700525
url:/G4/index.ered?reqCode=preferencesInit&jsessionid=tS1JTfPcFQcG3X5HQ2cSZDGGRvWLm2M11GBXssZ0SnyLRCCJwQhd!-680202136!1314852700525
jsessionid:XJ2FTfPpmvVLKnhhw7JYZnsCVVRBTkJYtGLGw9Zd1Twk1hJsvZMy!-680202136!1314852702563
0 请登录后投票
   发表时间:2011-09-01   最后修改:2011-09-01


新的调试信息:


我在url重写了jsessionid,为什么还会生成新的id cookie还要被重写

  • 大小: 99 KB
0 请登录后投票
   发表时间:2011-09-01  

问题继续扩散,Applet报表打印的session传递中Session也一样被覆盖丢失,而且在Weblogic9.2和weblogic10.3都存在此问题。IFrame的session覆盖丢失只在9.2版本中出现。

 


  • 大小: 31.1 KB
0 请登录后投票
   发表时间:2011-09-01  
eredlab 写道

问题继续扩散,Applet报表打印的session传递中Session也一样被覆盖丢失,而且在Weblogic9.2和weblogic10.3都存在此问题。IFrame的session覆盖丢失只在9.2版本中出现。

 


这个问题,我遇到过一个类似的,可能和这里的不一样。

 

分析:自从用了tomcat 7,默认开启了useHttpOnly="true",意思是,浏览器禁止插件访问敏感的cookie。

 

这样就导致applet或其他插件内部同服务器通信时,session的cookie时失败,所以服务器就分配了一个新的session cookie给插件。

 

解决也简单设置useHttpOnly="false"即可

 

0 请登录后投票
   发表时间:2011-09-01  
eredlab 写道


新的调试信息:


我在url重写了jsessionid,为什么还会生成新的id cookie还要被重写

 

莫非是weblogic9和10的默认的安全设置不一样,非常有可能。

0 请登录后投票
   发表时间:2011-09-01   最后修改:2011-09-01

偶来结贴了!
楼上分析的很有道理。经过大量的查阅资料和实验分析得出下述结论:

 

1.发生这个问题的确是由于weblogic9.2(mp2)对session的安全管理级别上的特殊性导致,即缺省设置了<cookie-http-only>true</cookie-http-only>。由于这个安全级别导致脚本里或者插件里的请求无法发送cookie也给服务器,服务器没收到sessionid便重新生成了一个新的ID将原有ID覆盖。造成一些特殊请求session被覆盖丢失的现象。

 

cookie-http-only                  
true
Specifies whether HttpOnly cookies are enabled. When this element is set to true, all session cookies would be unavailable to the browser scripts. The default value is true. Therefore, HttpOnly cookies are enabled by default.

2.weblogic9.2(mp2)缺省值为true,可气的是在weblogic.xml中没有提供修改这个参数。要设置这个参数必须升级到weblogic9.2(mp4)及以上版本。

 

解决办法:

升级到weblogic9.24也即9.2(mp4)版本及以上版本,在weblogic.xml中做如下配置便可:

 

	<session-descriptor>
		<cookie-http-only>false</cookie-http-only>
	</session-descriptor>

 参考文献:

 

http://download.oracle.com/docs/cd/E13222_01/wls/docs92/webapp/weblogic_xml.html

http://serverfault.com/questions/151107/http-only-cookies-in-weblogic-what-versions-support-them-how-and-why-are-they-su

http://cn.forums.oracle.com/forums/thread.jspa?threadID=1518073

http://cn.forums.oracle.com/forums/thread.jspa?threadID=953056

0 请登录后投票
   发表时间:2011-09-02  
记住了,以后类似问题,也好有个思路。哎,我们客户要在用weblogic8.15 郁闷,他们就不能升级一下吗?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics