(1)合规方案
为避免会话标识符易被猜测,Session ID应具备随机性。
(2)安全编码示例:
由中间件控制Session ID的生成。
在Apache Tomcat中,可通过context.xml的
<Manager
sessionIdLength="20"
pathname="SESSIONS.ser"
maxActiveSessions="8000"
secureRandomAlgorithm="SHA1PRNG"
secureRandomClass="java.security.SecureRandom"
/>
相关的配置属性设置解释如下表:
属性 | 描述 |
---|---|
sessionIdLength | 服务器端生成SessionID的长度,默认长度为16字节 |
pathname | 指定服务器端session值存放文件 |
maxActiveSessions | 会话管理器创建会话的最大数量,当值为-1时为不指定最大会话数量。若超出指定的最大数量,新创建会话将失败。 |
secureRandomAlgorithm | 指定生成SessionID的种子算法,用于初始化SecureRandom实例对象,默认为SHA1PRNG |
secureRandomClass | 指定创建SessionID会话的类,默认值为java.security.SecureRandom; |
将通过tomcat的配置文件,指定SessionID的生成方式,通过配置安全随机算法来保证SessionID的随机性。
服务器端自主生成Session ID。
当用户的登录成功后,应注销原来的Session ID并生成新的Session ID。参考如下代码:
public HttpSession changeSessionIdentifier(HttpServletRequest request) throws AuthenticationException {
// get the current session
HttpSession oldSession = request.getSession();
// make a copy of the session content
Map<String, Object> temp = new ConcurrentHashMap<String, Object>();
Enumeration e = oldSession.getAttributeNames();
while (e != null && e.hasMoreElements()) {
String name = (String) e.nextElement();
Object value = oldSession.getAttribute(name);
temp.put(name, value);
}
// kill the old session and create a new one
oldSession.invalidate();
HttpSession newSession = request.getSession();
User user = ESAPI.authenticator().getCurrentUser();
user.addSession(newSession);
user.removeSession(oldSession);
// copy back the session content
for (Map.Entry<String, Object> stringObjectEntry : temp.entrySet()) {
newSession.setAttribute(stringObjectEntry.getKey(), stringObjectEntry.getValue());
}
return newSession;
}