(1)合规方案
    为避免会话标识符易被猜测,Session ID应具备随机性。
    (2)安全编码示例:
    由中间件控制Session ID的生成。
    在Apache Tomcat中,可通过context.xml的节点配置SessionID的生成算法及字符长度;

    1. <Manager
    2. sessionIdLength="20"
    3. pathname="SESSIONS.ser"
    4. maxActiveSessions="8000"
    5. secureRandomAlgorithm="SHA1PRNG"
    6. secureRandomClass="java.security.SecureRandom"
    7. />

    相关的配置属性设置解释如下表:

    属性 描述
    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。参考如下代码:

    1. public HttpSession changeSessionIdentifier(HttpServletRequest request) throws AuthenticationException {
    2. // get the current session
    3. HttpSession oldSession = request.getSession();
    4. // make a copy of the session content
    5. Map<String, Object> temp = new ConcurrentHashMap<String, Object>();
    6. Enumeration e = oldSession.getAttributeNames();
    7. while (e != null && e.hasMoreElements()) {
    8. String name = (String) e.nextElement();
    9. Object value = oldSession.getAttribute(name);
    10. temp.put(name, value);
    11. }
    12. // kill the old session and create a new one
    13. oldSession.invalidate();
    14. HttpSession newSession = request.getSession();
    15. User user = ESAPI.authenticator().getCurrentUser();
    16. user.addSession(newSession);
    17. user.removeSession(oldSession);
    18. // copy back the session content
    19. for (Map.Entry<String, Object> stringObjectEntry : temp.entrySet()) {
    20. newSession.setAttribute(stringObjectEntry.getKey(), stringObjectEntry.getValue());
    21. }
    22. return newSession;
    23. }