View Javadoc

1   /*
2    * $Id: TokenHelper.java 441909 2006-09-10 05:28:16Z mrdon $
3    *
4    * Copyright 2006 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  package org.apache.struts2.util;
19  
20  import java.math.BigInteger;
21  import java.util.Map;
22  import java.util.Random;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  import com.opensymphony.xwork2.ActionContext;
28  import com.opensymphony.xwork2.util.LocalizedTextUtil;
29  
30  /***
31   * TokenHelper
32   *
33   */
34  public class TokenHelper {
35  
36      /***
37       * The default name to map the token value
38       */
39      public static final String DEFAULT_TOKEN_NAME = "struts.token";
40      
41      /***
42       * The name of the field which will hold the token name
43       */
44      public static final String TOKEN_NAME_FIELD = "struts.token.name";
45      private static final Log LOG = LogFactory.getLog(TokenHelper.class);
46      private static final Random RANDOM = new Random();
47  
48  
49      /***
50       * Sets a transaction token into the session using the default token name.
51       *
52       * @return the token string
53       */
54      public static String setToken() {
55          return setToken(DEFAULT_TOKEN_NAME);
56      }
57  
58      /***
59       * Sets a transaction token into the session using the provided token name.
60       *
61       * @param tokenName the name to store into the session with the token as the value
62       * @return the token string
63       */
64      public static String setToken(String tokenName) {
65          Map session = ActionContext.getContext().getSession();
66          String token = generateGUID();
67          try {
68          	session.put(tokenName, token);
69          }
70          catch(IllegalStateException e) {
71          	// WW-1182 explain to user what the problem is
72          	String msg = "Error creating HttpSession due response is commited to client. You can use the CreateSessionInterceptor or create the HttpSession from your action before the result is rendered to the client: " + e.getMessage();
73          	LOG.error(msg, e);
74          	throw new IllegalArgumentException(msg);
75          }
76  
77          return token;
78      }
79  
80      
81      /***
82       * Gets a transaction token into the session using the default token name.
83       * 
84       * @return token
85       */
86      public static String getToken() {
87      	return getToken(DEFAULT_TOKEN_NAME);
88      }
89      
90      /***
91       * Gets the Token value from the params in the ServletActionContext using the given name
92       *
93       * @param tokenName the name of the parameter which holds the token value
94       * @return the token String or null, if the token could not be found
95       */
96      public static String getToken(String tokenName) {
97          Map params = ActionContext.getContext().getParameters();
98          String[] tokens = (String[]) params.get(tokenName);
99          String token;
100 
101         if ((tokens == null) || (tokens.length < 1)) {
102             LOG.warn("Could not find token mapped to token name " + tokenName);
103 
104             return null;
105         }
106 
107         token = tokens[0];
108 
109         return token;
110     }
111 
112     /***
113      * Gets the token name from the Parameters in the ServletActionContext
114      *
115      * @return the token name found in the params, or null if it could not be found
116      */
117     public static String getTokenName() {
118         Map params = ActionContext.getContext().getParameters();
119 
120         if (!params.containsKey(TOKEN_NAME_FIELD)) {
121             LOG.warn("Could not find token name in params.");
122 
123             return null;
124         }
125 
126         String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD);
127         String tokenName;
128 
129         if ((tokenNames == null) || (tokenNames.length < 1)) {
130             LOG.warn("Got a null or empty token name.");
131 
132             return null;
133         }
134 
135         tokenName = tokenNames[0];
136 
137         return tokenName;
138     }
139 
140     /***
141      * Checks for a valid transaction token in the current request params. If a valid token is found, it is
142      * removed so the it is not valid again.
143      *
144      * @return false if there was no token set into the params (check by looking for {@link #TOKEN_NAME_FIELD}), true if a valid token is found
145      */
146     public static boolean validToken() {
147         String tokenName = getTokenName();
148 
149         if (tokenName == null) {
150         	if (LOG.isDebugEnabled())
151         		LOG.debug("no token name found -> Invalid token ");
152             return false;
153         }
154 
155         String token = getToken(tokenName);
156 
157         if (token == null) {
158         	if (LOG.isDebugEnabled()) 
159         		LOG.debug("no token found for token name "+tokenName+" -> Invalid token ");
160             return false;
161         }
162 
163         Map session = ActionContext.getContext().getSession();
164         String sessionToken = (String) session.get(tokenName);
165 
166         if (!token.equals(sessionToken)) {
167             LOG.warn(LocalizedTextUtil.findText(TokenHelper.class, "struts.internal.invalid.token", ActionContext.getContext().getLocale(), "Form token {0} does not match the session token {1}.", new Object[]{
168                     token, sessionToken
169             }));
170 
171             return false;
172         }
173 
174         // remove the token so it won't be used again
175         session.remove(tokenName);
176 
177         return true;
178     }
179     
180     public static String generateGUID() {
181         return new BigInteger(165, RANDOM).toString(36).toUpperCase();
182     }
183 }