1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application.viewstate;
20
21 import java.util.Map;
22 import java.util.Random;
23 import javax.faces.context.ExternalContext;
24 import javax.faces.context.FacesContext;
25 import javax.xml.bind.DatatypeConverter;
26
27 import org.apache.myfaces.application.StateCache;
28 import org.apache.myfaces.shared.renderkit.RendererUtils;
29 import org.apache.myfaces.shared.util.WebConfigParamUtils;
30
31
32
33
34
35 class RandomCsrfSessionTokenFactory extends CsrfSessionTokenFactory
36 {
37 private final Random random;
38 private final int length;
39
40 public RandomCsrfSessionTokenFactory(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 random = new Random(((int) System.nanoTime()) + this.hashCode());
47 }
48
49 public Integer generateCounterKey(FacesContext facesContext)
50 {
51 ExternalContext externalContext = facesContext.getExternalContext();
52 Object sessionObj = externalContext.getSession(true);
53 Integer sequence;
54 synchronized (sessionObj)
55 {
56 Map<String, Object> map = externalContext.getSessionMap();
57 sequence = (Integer) map.get(RendererUtils.SEQUENCE_PARAM);
58 if (sequence == null || sequence.intValue() == Integer.MAX_VALUE)
59 {
60 sequence = Integer.valueOf(1);
61 }
62 else
63 {
64 sequence = Integer.valueOf(sequence.intValue() + 1);
65 }
66 map.put(RendererUtils.SEQUENCE_PARAM, sequence);
67 }
68 return sequence;
69 }
70
71 public byte[] generateKey(FacesContext facesContext)
72 {
73 byte[] array = new byte[length];
74 random.nextBytes(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 }