本文是基于apache-tomcat-7.0.54。
阅读了创建session的源码,发现有极小的可能性,session会被覆盖(不安全)。 下面从ManagerBase的createSession方法开始
@Override public Session createSession(String sessionId) { if ((maxActiveSessions >= 0) && (getActiveSessions() >= maxActiveSessions)) { rejectedSessions++; throw new TooManyActiveSessionsException( sm.getString("managerBase.createSession.ise"), maxActiveSessions); } // Recycle or create a Session instance Session session = createEmptySession(); // Initialize the properties of the new session and return it session.setNew(true); session.setValid(true); session.setCreationTime(System.currentTimeMillis()); session.setMaxInactiveInterval(this.maxInactiveInterval); String id = sessionId; if (id == null) { id = generateSessionId(); } session.setId(id); sessionCounter++; SessionTiming timing = new SessionTiming(session.getCreationTime(), 0); synchronized (sessionCreationTiming) { sessionCreationTiming.add(timing); sessionCreationTiming.poll(); } return (session);generateSessionId方法}
protected String generateSessionId() { String result = null; do { if (result != null) { // Not thread-safe but if one of multiple increments is lost // that is not a big deal since the fact that there was any // duplicate is a much bigger issue. duplicates++; } result = sessionIdGenerator.generateSessionId(); } while (sessions.containsKey(result)); return result; }创建sessionId时会判断sessions(sessions是ConcurrentHashMap)中是否存在,若存在则一直循环,直到唯一。 新创建的session是session.setId(id)写入的。
假设这样一种情况,通过generateSessionId得到了第一个sessionIdA,这时还没有session.setId(sessionIdA), generateSessionId又创建了一个sessionIdB,恰巧sessionIdA=sessionIdB(这种几率非常低),这种情况下,前一个session就会被后一个session覆盖。
我们在SessionIdGenerator中写个main方法,测试下是否会出现sessionId重复的情况。
public static void main(String[] args) { SessionIdGenerator generator = new SessionIdGenerator(); generator.setSessionIdLength(5); MapsessionIdLength默认值为16,这种情况下,很难重复。于是我改为了5,在有限时间内重复一般都会出现。map = new HashMap (); for(int i=0; i< 100000000; i++) { String key = generator.generateSessionId(); if(map.containsKey(key)) { System.out.println("i= " + i + " " + key); break; } map.put(key, null); } }
结论:tomcat的session在极小概率的情况下会有问题。
若分析有误,希望提出来,谢谢。