在我们打开web页面的时候,会有一个sessionId,登录之后,这个seesionId的值没变,一致存在,这种可能会变成会话固化安全漏洞,因此我们需要解决这种问题。解决方法很简单,在登录后改变这个会话的sessionId,这样这个未授权时的会话seesionId自然就失效,也不会产生固化的僵尸会话。
一、在解决该问题之前,需要了解session会话的创建,session的创建方式主要有以下3种:
//1、这是大家最喜欢用的一种
HttpSession session = request.getSession();
//2、这种用法和1是一个效果, 获取session,如果存在则返回session,不存在则重新创建一个
HttpSession session = request.getSession(true);
//3、这种用法被很多人忽略,获取session,如果存在返回session,不存在则返回null
HttpSession session = request.getSession(false);
需要注意:request.getSession()和request.getSession(true)等效,只有当session一定存在或者sesson不存在时明确有创建session的需要,否则尽量使用request.getSession(false)。在实际的生产中,有时我们会把某些信息存在session当中,在这种场景当中,获取session的正确方法应该是:
String userName = "";
HttpSession session = request.getSession(false);
if(session != null){
userName = (String)session.getAttribute("userName");
}
二、如果项目中用到了Spring(其实只要是Java的稍大的项目,Spring是一个很好的选择),对session的操作就方便很多。如果需要在Session中取值,可以用WebUtils工具(org.springframework.web.util.WebUtils)的getSessionAttribute(HttpServletRequest request, String name)方法。源码如下:
/**
* Check the given request for a session attribute of the given name.
* Returns null if there is no session or if the session has no such attribute.
* Does not create a new session if none has existed before!
* @param request current HTTP request
* @param name the name of the session attribute
* @return the value of the session attribute, or <code>null</code> if not found
*/
public static Object getSessionAttribute(HttpServletRequest request, String name) {
Assert.notNull(request, "Request must not be null");
HttpSession session = request.getSession(false);
return (session != null ? session.getAttribute(name) : null);
}
自己使用在项目中直接使用:
String userName = WebUtils.getSessionAttribute(reqeust, "userName");
三、web登陆前后改变sessionId标识
上面介绍了这么多,现在进入问题主题,登录前和登录后sessionId的更换。直接上代码,一目了然:
//先验证登录成功之后再进行更换sessionId
HttpSession oldSession = request.getSession(false);
if(oldSession != null){
oldSession.invalidate(); //废除掉登陆前的session
}
request.getSession(true); //重新生成一个session,此时,登录前和登录后的sessionId就不一致了
//如果登录前session中的内容需要保留至整个项目,可以在这里将原来session中的内容重新拷贝到新的session中
//TODO
此时,再去查看登陆前和登陆后sessionId,发现已经更改,问题解决。