1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.util.storage;
18
19 import java.util.concurrent.locks.ReentrantLock;
20
21 import org.joda.time.DateTime;
22 import org.opensaml.xml.util.DatatypeHelper;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26
27
28
29
30
31
32
33 public class ReplayCache {
34
35
36 private final Logger log = LoggerFactory.getLogger(ReplayCache.class);
37
38
39 private StorageService<String, ReplayCacheEntry> storage;
40
41
42 private String partition;
43
44
45 private long entryDuration;
46
47
48 private ReentrantLock cacheLock;
49
50
51
52
53
54
55
56 public ReplayCache(StorageService<String, ReplayCacheEntry> storageService, long duration) {
57 storage = storageService;
58 entryDuration = duration;
59 partition = "replay";
60 cacheLock = new ReentrantLock(true);
61 }
62
63
64
65
66
67
68
69
70 public ReplayCache(StorageService<String, ReplayCacheEntry> storageService, String storageParition, long duration) {
71 storage = storageService;
72 entryDuration = duration;
73 if (!DatatypeHelper.isEmpty(storageParition)) {
74 partition = DatatypeHelper.safeTrim(storageParition);
75 } else {
76 partition = "replay";
77 }
78 cacheLock = new ReentrantLock(true);
79 }
80
81
82
83
84
85
86
87
88
89
90 public boolean isReplay(String issuerId, String messageId) {
91 log.debug("Attempting to acquire lock for replay cache check");
92 cacheLock.lock();
93 log.debug("Lock acquired");
94
95 try {
96 boolean replayed = true;
97 String entryHash = issuerId + messageId;
98
99 ReplayCacheEntry cacheEntry = storage.get(partition, entryHash);
100
101 if (cacheEntry == null || cacheEntry.isExpired()) {
102 if (log.isDebugEnabled()) {
103 if (cacheEntry == null) {
104 log.debug("Message ID {} was not a replay", messageId);
105 } else if (cacheEntry.isExpired()) {
106 log.debug("Message ID {} expired in replay cache at {}", messageId, cacheEntry
107 .getExpirationTime().toString());
108 storage.remove(partition, entryHash);
109 }
110 }
111 replayed = false;
112 addMessageID(entryHash, new DateTime().plus(entryDuration));
113 } else {
114 log.debug("Replay of message ID {} detected in replay cache, will expire at {}", messageId, cacheEntry
115 .getExpirationTime().toString());
116 }
117
118 return replayed;
119 } finally {
120 cacheLock.unlock();
121 }
122 }
123
124
125
126
127
128
129
130 protected void addMessageID(String messageId, DateTime expiration) {
131 log.debug("Writing message ID {} to replay cache with expiration time {}", messageId, expiration.toString());
132 storage.put(partition, messageId, new ReplayCacheEntry(messageId, expiration));
133 }
134 }