1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
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 }