View Javadoc

1   /*
2    * Copyright 2004-2008 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.util;
17  
18  import static org.seasar.cubby.CubbyConstants.ATTR_TOKEN;
19  
20  import java.math.BigInteger;
21  import java.util.Map;
22  import java.util.Random;
23  
24  import javax.servlet.http.HttpSession;
25  
26  import org.seasar.cubby.CubbyConstants;
27  import org.seasar.cubby.tags.TokenTag;
28  import org.seasar.cubby.validator.validators.TokenValidator;
29  import org.seasar.framework.util.LruHashMap;
30  
31  /**
32   * 2重サブミット防止処理のヘルパークラス
33   * @see TokenTag
34   * @see TokenValidator
35   * @author agata
36   */
37  public class TokenHelper {
38  
39  	/**
40  	 * トークン用Mapに保持するトークンの個数(1セッションあたり何個のトークンを保持するか?)
41  	 */
42  	public static int TOKEN_HISTORY_SIZE = 16;
43  
44  	/**
45  	 * デフォルトのトークン用パラメータ名
46  	 */
47      public static final String DEFAULT_TOKEN_NAME = "cubby.token";
48  
49      /**
50       * トークン生成用のランダムクラス
51       */
52      private static final Random RANDOM = new Random();
53  	
54      /**
55       * ユニークなトークンを生成します。
56       * @return ユニークなトークン
57       */
58      public static String generateGUID() {
59          return new BigInteger(165, RANDOM).toString(36).toUpperCase();
60      }    
61  
62      /**
63       * トークン用のマップをセッションから取得します。
64       * <p>
65       * セッション中にトークン用のマップが存在しない場合、新規に生成します。
66       * トークン用のマップは{@link LruHashMap}を使い、トークンの保持上限付きのMapになります。
67       * </p>
68       * @param session セッション
69       * @return トークン用のマップ
70       */
71  	@SuppressWarnings("unchecked")
72  	public
73  	static Map<String, String> getTokenMap(HttpSession session) {
74  		Map<String, String> tokenMap = (Map<String, String>) session.getAttribute(CubbyConstants.ATTR_TOKEN);
75  		if (tokenMap == null) {
76  			tokenMap = new LruHashMap(TOKEN_HISTORY_SIZE);
77  			session.setAttribute(ATTR_TOKEN, tokenMap);
78  		}
79  		return tokenMap;
80  	}
81  	
82  	/**
83  	 * トークンをセッション中のトークン用のMapにセットします。
84  	 * @param session セッション
85  	 * @param token トークン文字列
86  	 */
87  	public static void setToken(HttpSession session, String token) {
88  		Map<String, String> tokenMap = getTokenMap(session);
89  		synchronized (tokenMap) {
90  			tokenMap.put(token, null);
91  		}
92  	}
93  
94  	/**
95  	 * パラメータ中のトークン文字列とセッション中のトークン文字列を検証します。
96  	 * <p>
97  	 * セッション中に格納されたトークン用のMapのキーに、
98  	 * 指定されたトークン文字列が含まれるかどうかを判定し、Mapから取り除きます。
99  	 * </p>
100 	 * @param session セッション
101 	 * @param token トークン文字列
102 	 * @return 指定されたトークン文字列がセッション中に存在したら<code>true</code>、それ以外は<code>false</code>
103 	 */
104 	public static boolean validateToken(HttpSession session,
105 			String token) {
106 		Map<String, String> tokenMap = getTokenMap(session);
107 		synchronized (tokenMap) {
108 			boolean success = tokenMap.containsKey(token);
109 			tokenMap.remove(token);
110 			return success;
111 		}
112 	}
113 }