View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.application.viewstate;
20  
21  import javax.faces.context.FacesContext;
22  import javax.xml.bind.DatatypeConverter;
23  
24  import org.apache.myfaces.application.StateCache;
25  import org.apache.myfaces.shared.util.WebConfigParamUtils;
26  
27  /**
28   * This factory generate a key composed by a counter and a random number. The
29   * counter ensures uniqueness, and the random number prevents guess the next
30   * session token.
31   * 
32   * @since 2.2
33   * @author Leonardo Uribe
34   */
35  class SecureRandomCsrfSessionTokenFactory extends CsrfSessionTokenFactory
36  {
37      private final SessionIdGenerator sessionIdGenerator;
38      private final int length;
39  
40      public SecureRandomCsrfSessionTokenFactory(FacesContext facesContext)
41      {
42          length = WebConfigParamUtils.getIntegerInitParameter(
43              facesContext.getExternalContext(), 
44              StateCache.RANDOM_KEY_IN_CSRF_SESSION_TOKEN_LENGTH_PARAM, 
45              StateCache.RANDOM_KEY_IN_CSRF_SESSION_TOKEN_LENGTH_PARAM_DEFAULT);
46          sessionIdGenerator = new SessionIdGenerator();
47          sessionIdGenerator.setSessionIdLength(length);
48          String secureRandomClass = WebConfigParamUtils.getStringInitParameter(
49              facesContext.getExternalContext(), 
50              StateCache.RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM_CLASS_PARAM);
51          if (secureRandomClass != null)
52          {
53              sessionIdGenerator.setSecureRandomClass(secureRandomClass);
54          }
55          String secureRandomProvider = WebConfigParamUtils.getStringInitParameter(
56              facesContext.getExternalContext(), 
57              StateCache.RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM_PROVIDER_PARAM);
58          if (secureRandomProvider != null)
59          {
60              sessionIdGenerator.setSecureRandomProvider(secureRandomProvider);
61          }
62          String secureRandomAlgorithm = WebConfigParamUtils.getStringInitParameter(
63              facesContext.getExternalContext(), 
64              StateCache.RANDOM_KEY_IN_CSRF_SESSION_TOKEN_SECURE_RANDOM_ALGORITM_PARAM);
65          if (secureRandomAlgorithm != null)
66          {
67              sessionIdGenerator.setSecureRandomAlgorithm(secureRandomAlgorithm);
68          }
69      }
70  
71      public byte[] generateKey(FacesContext facesContext)
72      {
73          byte[] array = new byte[length];
74          sessionIdGenerator.getRandomBytes(array);
75          return array;
76      }
77  
78      @Override
79      public String createCryptographicallyStrongTokenFromSession(FacesContext context)
80      {
81          byte[] key = generateKey(context);
82          return DatatypeConverter.printHexBinary(key);
83      }
84  }