KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > util > TokenProcessor


1 /*
2  * $Id: TokenProcessor.java 54929 2004-10-16 16:38:42Z germuska $
3  *
4  * Copyright 2003-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 package org.apache.struts.util;
20
21 import java.security.MessageDigest JavaDoc;
22 import java.security.NoSuchAlgorithmException JavaDoc;
23
24 import javax.servlet.http.HttpServletRequest JavaDoc;
25 import javax.servlet.http.HttpSession JavaDoc;
26
27 import org.apache.struts.Globals;
28 import org.apache.struts.taglib.html.Constants;
29
30 /**
31  * TokenProcessor is responsible for handling all token related functionality. The
32  * methods in this class are synchronized to protect token processing from multiple
33  * threads. Servlet containers are allowed to return a different HttpSession object
34  * for two threads accessing the same session so it is not possible to synchronize
35  * on the session.
36  *
37  * @since Struts 1.1
38  */

39 public class TokenProcessor {
40
41     /**
42      * The singleton instance of this class.
43      */

44     private static TokenProcessor instance = new TokenProcessor();
45
46     /**
47      * Retrieves the singleton instance of this class.
48      */

49     public static TokenProcessor getInstance() {
50         return instance;
51     }
52
53     /**
54      * Protected constructor for TokenProcessor. Use TokenProcessor.getInstance()
55      * to obtain a reference to the processor.
56      */

57     protected TokenProcessor() {
58         super();
59     }
60
61     /**
62      * The timestamp used most recently to generate a token value.
63      */

64     private long previous;
65
66     /**
67      * Return <code>true</code> if there is a transaction token stored in
68      * the user's current session, and the value submitted as a request
69      * parameter with this action matches it. Returns <code>false</code>
70      * under any of the following circumstances:
71      * <ul>
72      * <li>No session associated with this request</li>
73      * <li>No transaction token saved in the session</li>
74      * <li>No transaction token included as a request parameter</li>
75      * <li>The included transaction token value does not match the
76      * transaction token in the user's session</li>
77      * </ul>
78      *
79      * @param request The servlet request we are processing
80      */

81     public synchronized boolean isTokenValid(HttpServletRequest JavaDoc request) {
82         return this.isTokenValid(request, false);
83     }
84
85     /**
86      * Return <code>true</code> if there is a transaction token stored in
87      * the user's current session, and the value submitted as a request
88      * parameter with this action matches it. Returns <code>false</code>
89      * <ul>
90      * <li>No session associated with this request</li>
91      * <li>No transaction token saved in the session</li>
92      * <li>No transaction token included as a request parameter</li>
93      * <li>The included transaction token value does not match the
94      * transaction token in the user's session</li>
95      * </ul>
96      *
97      * @param request The servlet request we are processing
98      * @param reset Should we reset the token after checking it?
99      */

100     public synchronized boolean isTokenValid(
101         HttpServletRequest JavaDoc request,
102         boolean reset) {
103
104         // Retrieve the current session for this request
105
HttpSession JavaDoc session = request.getSession(false);
106         if (session == null) {
107             return false;
108         }
109
110         // Retrieve the transaction token from this session, and
111
// reset it if requested
112
String JavaDoc saved = (String JavaDoc) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);
113         if (saved == null) {
114             return false;
115         }
116
117         if (reset) {
118             this.resetToken(request);
119         }
120
121         // Retrieve the transaction token included in this request
122
String JavaDoc token = request.getParameter(Constants.TOKEN_KEY);
123         if (token == null) {
124             return false;
125         }
126
127         return saved.equals(token);
128     }
129
130     /**
131      * Reset the saved transaction token in the user's session. This
132      * indicates that transactional token checking will not be needed
133      * on the next request that is submitted.
134      *
135      * @param request The servlet request we are processing
136      */

137     public synchronized void resetToken(HttpServletRequest JavaDoc request) {
138
139         HttpSession JavaDoc session = request.getSession(false);
140         if (session == null) {
141             return;
142         }
143         session.removeAttribute(Globals.TRANSACTION_TOKEN_KEY);
144     }
145
146     /**
147      * Save a new transaction token in the user's current session, creating
148      * a new session if necessary.
149      *
150      * @param request The servlet request we are processing
151      */

152     public synchronized void saveToken(HttpServletRequest JavaDoc request) {
153
154         HttpSession JavaDoc session = request.getSession();
155         String JavaDoc token = generateToken(request);
156         if (token != null) {
157             session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);
158         }
159
160     }
161
162     /**
163      * Generate a new transaction token, to be used for enforcing a single
164      * request for a particular transaction.
165      *
166      * @param request The request we are processing
167      */

168     public synchronized String JavaDoc generateToken(HttpServletRequest JavaDoc request) {
169
170         HttpSession JavaDoc session = request.getSession();
171         try {
172             byte id[] = session.getId().getBytes();
173             long current = System.currentTimeMillis();
174             if (current == previous) {
175                 current++;
176             }
177             previous = current;
178             byte now[] = new Long JavaDoc(current).toString().getBytes();
179             MessageDigest JavaDoc md = MessageDigest.getInstance("MD5");
180             md.update(id);
181             md.update(now);
182             return toHex(md.digest());
183         } catch (NoSuchAlgorithmException JavaDoc e) {
184             return null;
185         }
186
187     }
188
189     /**
190      * Convert a byte array to a String of hexadecimal digits and return it.
191      * @param buffer The byte array to be converted
192      */

193     private String JavaDoc toHex(byte buffer[]) {
194         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(buffer.length * 2);
195         for (int i = 0; i < buffer.length; i++) {
196             sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
197             sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
198         }
199         return sb.toString();
200     }
201
202 }
203
Popular Tags