If at the end of your application workflow, there is a natural place to do session.invalidate(), then sure, I encourage you to do that. That will save you memory.
Session ids are generated from a VM singleton, using a random generator seeded by a timestamp and the VM's free memory (which are unlikely to be duplicated across VMs in a cluster). The class follows, in case you are interested. I've never heard a case of this algorithm generating noticeable duplicate ids. I have seen reports on this forum of non-clustered webapps getting duplicate ids when more than one JBoss instance is on the same machine. But clustered session ids use a different algorithm. Have you heard of more than 1 case of this? If you have, that would in my mind pretty much rule out a chance session id collision. Anyway, invalidating the session if you know its done would reduce the already extremely low chance of a problem from session id collision. Here's the SessionIDGenerator class: | /* | * JBoss, Home of Professional Open Source. | * Copyright 2006, Red Hat Middleware LLC, and individual contributors | * as indicated by the @author tags. See the copyright.txt file in the | * distribution for a full listing of individual contributors. | * | * This is free software; you can redistribute it and/or modify it | * under the terms of the GNU Lesser General Public License as | * published by the Free Software Foundation; either version 2.1 of | * the License, or (at your option) any later version. | * | * This software is distributed in the hope that it will be useful, | * but WITHOUT ANY WARRANTY; without even the implied warranty of | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | * Lesser General Public License for more details. | * | * You should have received a copy of the GNU Lesser General Public | * License along with this software; if not, write to the Free | * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | */ | package org.jboss.web.tomcat.service.session; | | import java.util.Collection; | import java.util.HashSet; | import java.util.Iterator; | import java.util.Random; | import java.security.MessageDigest; | import java.security.NoSuchAlgorithmException; | import java.security.SecureRandom; | | import org.jboss.logging.Logger; | | /** | * Unique session id generator | * | * @author Ben Wang | */ | public class SessionIDGenerator | { | protected final static int SESSION_ID_BYTES = 16; // We want 16 Bytes for the session-id | protected final static String SESSION_ID_HASH_ALGORITHM = "MD5"; | protected final static String SESSION_ID_RANDOM_ALGORITHM = "SHA1PRNG"; | protected final static String SESSION_ID_RANDOM_ALGORITHM_ALT = "IBMSecureRandom"; | protected Logger log = Logger.getLogger(SessionIDGenerator.class); | | protected MessageDigest digest = null; | protected Random random = null; | protected static final SessionIDGenerator s_ = new SessionIDGenerator(); | | protected String sessionIdAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-*"; | | public static SessionIDGenerator getInstance() | { | return s_; | } | | /** | * The SessionIdAlphabet is the set of characters used to create a session Id | */ | public void setSessionIdAlphabet(String sessionIdAlphabet) | { | if (sessionIdAlphabet.length() != 65) { | throw new IllegalArgumentException("SessionIdAlphabet must be exactly 65 characters long"); | } | | checkDuplicateChars(sessionIdAlphabet); | | this.sessionIdAlphabet = sessionIdAlphabet; | } | | protected void checkDuplicateChars(String sessionIdAlphabet) { | char[] alphabet = sessionIdAlphabet.toCharArray(); | for (int i=0; i < alphabet.length; i++) { | if (!uniqueChar(alphabet, sessionIdAlphabet)) { | throw new IllegalArgumentException("All chars in SessionIdAlphabet must be unique"); | } | } | } | | // does a character appear in the String once and only once? | protected boolean uniqueChar(char c, String s) { | int firstIndex = s.indexOf(c); | if (firstIndex == -1) return false; | return s.indexOf(c, firstIndex + 1) == -1; | } | | /** | * The SessionIdAlphabet is the set of characters used to create a session Id | */ | public String getSessionIdAlphabet() { | return this.sessionIdAlphabet; | } | | public synchronized String getSessionId() | { | String id = generateSessionId(); | if (log.isDebugEnabled()) | log.debug("getSessionId called: " + id); | return id; | } | | | /** | * Generate a session-id that is not guessable | * | * @return generated session-id | */ | protected synchronized String generateSessionId() | { | if (this.digest == null) | { | this.digest = getDigest(); | } | | if (this.random == null) | { | this.random = getRandom(); | } | | byte[] bytes = new byte[SESSION_ID_BYTES]; | | // get random bytes | this.random.nextBytes(bytes); | | // Hash the random bytes | bytes = this.digest.digest(bytes); | | // Render the result as a String of hexadecimal digits | return encode(bytes); | } | | /** | * Encode the bytes into a String with a slightly modified Base64-algorithm | * This code was written by Kevin Kelley <[EMAIL PROTECTED]> | * and adapted by Thomas Peuss <[EMAIL PROTECTED]> | * | * @param data The bytes you want to encode | * @return the encoded String | */ | protected String encode(byte[] data) | { | char[] out = new char[((data.length + 2) / 3) * 4]; | char[] alphabet = this.sessionIdAlphabet.toCharArray(); | | // | // 3 bytes encode to 4 chars. Output is always an even | // multiple of 4 characters. | // | for (int i = 0, index = 0; i < data.length; i += 3, index += 4) | { | boolean quad = false; | boolean trip = false; | | int val = (0xFF & (int) data); | val <<= 8; | if ((i + 1) < data.length) | { | val |= (0xFF & (int) data[i + 1]); | trip = true; | } | val <<= 8; | if ((i + 2) < data.length) | { | val |= (0xFF & (int) data[i + 2]); | quad = true; | } | out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)]; | val >>= 6; | out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)]; | val >>= 6; | out[index + 1] = alphabet[val & 0x3F]; | val >>= 6; | out[index + 0] = alphabet[val & 0x3F]; | } | return new String(out); | } | | /** | * get a random-number generator | * | * @return a random-number generator | */ | protected synchronized Random getRandom() | { | long seed; | Random random = null; | | // Mix up the seed a bit | seed = System.currentTimeMillis(); | seed ^= Runtime.getRuntime().freeMemory(); | | try | { | random = SecureRandom.getInstance(SESSION_ID_RANDOM_ALGORITHM); | } | catch (NoSuchAlgorithmException e) | { | try | { | random = SecureRandom.getInstance(SESSION_ID_RANDOM_ALGORITHM_ALT); | } | catch (NoSuchAlgorithmException e_alt) | { | log.error("Could not generate SecureRandom for session-id randomness", e); | log.error("Could not generate SecureRandom for session-id randomness", e_alt); | return null; | } | } | | // set the generated seed for this PRNG | random.setSeed(seed); | | return random; | } | | /** | * get a MessageDigest hash-generator | * | * @return a hash generator | */ | protected synchronized MessageDigest getDigest() | { | MessageDigest digest = null; | | try | { | digest = MessageDigest.getInstance(SESSION_ID_HASH_ALGORITHM); | } | catch (NoSuchAlgorithmException e) | { | log.error("Could not generate MessageDigest for session-id hashing", e); | return null; | } | | return digest; | } | | public static void main(String[] args) | { | SessionIDGenerator gen = SessionIDGenerator.getInstance(); | | HashSet set = new HashSet(); | String id = null; | for (int i = 0; i > -1; i++) | { | id = gen.getSessionId(); | | if (set.add(id) == false) | { | System.out.println(i + " FAILED -- duplicate id " + id); | break; | } | | if (i % 1000 == 0 && i > 0) | { | System.out.println("Tested " + i + " session ids"); | } | if (i % 50000 == 0 && set.size() > 450000) | { | System.out.println("Discarding..."); | int k = 0; | int discarded = 0; | for (Iterator it = set.iterator(); it.hasNext() && discarded < 50000; k++) | { | it.next(); | if (k % 10 == 0) | { | it.remove(); | discarded++; | } | } | System.out.println("Discarding completed"); | } | } | } | } | View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4114862#4114862 Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4114862 _______________________________________________ jboss-user mailing list jboss-user@lists.jboss.org https://lists.jboss.org/mailman/listinfo/jboss-user