View Javadoc

1   /*
2    * $Id: TokenHelper.java 651946 2008-04-27 13:41:38Z apetrelli $
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         Map params = ActionContext.getContext().getParameters();
101         String[] tokens = (String[]) params.get(tokenName);
102         String token;
103 
104         if ((tokens == null) || (tokens.length < 1)) {
105             LOG.warn("Could not find token mapped to token name " + tokenName);
106 
107             return null;
108         }
109 
110         token = tokens[0];
111 
112         return token;
113     }
114 
115     /***
116      * Gets the token name from the Parameters in the ServletActionContext
117      *
118      * @return the token name found in the params, or null if it could not be found
119      */
120     public static String getTokenName() {
121         Map params = ActionContext.getContext().getParameters();
122 
123         if (!params.containsKey(TOKEN_NAME_FIELD)) {
124             LOG.warn("Could not find token name in params.");
125 
126             return null;
127         }
128 
129         String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD);
130         String tokenName;
131 
132         if ((tokenNames == null) || (tokenNames.length < 1)) {
133             LOG.warn("Got a null or empty token name.");
134 
135             return null;
136         }
137 
138         tokenName = tokenNames[0];
139 
140         return tokenName;
141     }
142 
143     /***
144      * Checks for a valid transaction token in the current request params. If a valid token is found, it is
145      * removed so the it is not valid again.
146      *
147      * @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
148      */
149     public static boolean validToken() {
150         String tokenName = getTokenName();
151 
152         if (tokenName == null) {
153             if (LOG.isDebugEnabled())
154                 LOG.debug("no token name found -> Invalid token ");
155             return false;
156         }
157 
158         String token = getToken(tokenName);
159 
160         if (token == null) {
161             if (LOG.isDebugEnabled())
162                 LOG.debug("no token found for token name "+tokenName+" -> Invalid token ");
163             return false;
164         }
165 
166         Map session = ActionContext.getContext().getSession();
167         String sessionToken = (String) session.get(tokenName);
168 
169         if (!token.equals(sessionToken)) {
170             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[]{
171                     token, sessionToken
172             }));
173 
174             return false;
175         }
176 
177         // remove the token so it won't be used again
178         session.remove(tokenName);
179 
180         return true;
181     }
182 
183     public static String generateGUID() {
184         return new BigInteger(165, RANDOM).toString(36).toUpperCase();
185     }
186 }