View Javadoc

1   /*
2    * $Id: TokenHelper.java 781798 2009-06-04 17:08:35Z wesw $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.util;
23  
24  import java.math.BigInteger;
25  import java.util.Map;
26  import java.util.Random;
27  
28  import com.opensymphony.xwork2.ActionContext;
29  import com.opensymphony.xwork2.util.LocalizedTextUtil;
30  import com.opensymphony.xwork2.util.logging.Logger;
31  import com.opensymphony.xwork2.util.logging.LoggerFactory;
32  
33  /***
34   * TokenHelper
35   *
36   */
37  public class TokenHelper {
38  
39      /***
40       * The default name to map the token value
41       */
42      public static final String DEFAULT_TOKEN_NAME = "struts.token";
43  
44      /***
45       * The name of the field which will hold the token name
46       */
47      public static final String TOKEN_NAME_FIELD = "struts.token.name";
48      private static final Logger LOG = LoggerFactory.getLogger(TokenHelper.class);
49      private static final Random RANDOM = new Random();
50  
51  
52      /***
53       * Sets a transaction token into the session using the default token name.
54       *
55       * @return the token string
56       */
57      public static String setToken() {
58          return setToken(DEFAULT_TOKEN_NAME);
59      }
60  
61      /***
62       * Sets a transaction token into the session using the provided token name.
63       *
64       * @param tokenName the name to store into the session with the token as the value
65       * @return the token string
66       */
67      public static String setToken(String tokenName) {
68          Map session = ActionContext.getContext().getSession();
69          String token = generateGUID();
70          try {
71              session.put(tokenName, token);
72          }
73          catch(IllegalStateException e) {
74              // WW-1182 explain to user what the problem is
75              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();
76              LOG.error(msg, e);
77              throw new IllegalArgumentException(msg);
78          }
79  
80          return token;
81      }
82  
83  
84      /***
85       * Gets a transaction token into the session using the default token name.
86       *
87       * @return token
88       */
89      public static String getToken() {
90          return getToken(DEFAULT_TOKEN_NAME);
91      }
92  
93      /***
94       * Gets the Token value from the params in the ServletActionContext using the given name
95       *
96       * @param tokenName the name of the parameter which holds the token value
97       * @return the token String or null, if the token could not be found
98       */
99      public static String getToken(String tokenName) {
100         if (tokenName == null ) {
101             return null;
102         }
103         Map params = ActionContext.getContext().getParameters();
104         String[] tokens = (String[]) params.get(tokenName);
105         String token;
106 
107         if ((tokens == null) || (tokens.length < 1)) {
108             LOG.warn("Could not find token mapped to token name " + tokenName);
109 
110             return null;
111         }
112 
113         token = tokens[0];
114 
115         return token;
116     }
117 
118     /***
119      * Gets the token name from the Parameters in the ServletActionContext
120      *
121      * @return the token name found in the params, or null if it could not be found
122      */
123     public static String getTokenName() {
124         Map params = ActionContext.getContext().getParameters();
125 
126         if (!params.containsKey(TOKEN_NAME_FIELD)) {
127             LOG.warn("Could not find token name in params.");
128 
129             return null;
130         }
131 
132         String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD);
133         String tokenName;
134 
135         if ((tokenNames == null) || (tokenNames.length < 1)) {
136             LOG.warn("Got a null or empty token name.");
137 
138             return null;
139         }
140 
141         tokenName = tokenNames[0];
142 
143         return tokenName;
144     }
145 
146     /***
147      * Checks for a valid transaction token in the current request params. If a valid token is found, it is
148      * removed so the it is not valid again.
149      *
150      * @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
151      */
152     public static boolean validToken() {
153         String tokenName = getTokenName();
154 
155         if (tokenName == null) {
156             if (LOG.isDebugEnabled())
157                 LOG.debug("no token name found -> Invalid token ");
158             return false;
159         }
160 
161         String token = getToken(tokenName);
162 
163         if (token == null) {
164             if (LOG.isDebugEnabled())
165                 LOG.debug("no token found for token name "+tokenName+" -> Invalid token ");
166             return false;
167         }
168 
169         Map session = ActionContext.getContext().getSession();
170         String sessionToken = (String) session.get(tokenName);
171 
172         if (!token.equals(sessionToken)) {
173             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[]{
174                     token, sessionToken
175             }));
176 
177             return false;
178         }
179 
180         // remove the token so it won't be used again
181         session.remove(tokenName);
182 
183         return true;
184     }
185 
186     public static String generateGUID() {
187         return new BigInteger(165, RANDOM).toString(36).toUpperCase();
188     }
189 }