1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.common.binding.security;
18
19 import org.opensaml.common.binding.SAMLMessageContext;
20 import org.opensaml.util.storage.ReplayCache;
21 import org.opensaml.ws.message.MessageContext;
22 import org.opensaml.ws.security.SecurityPolicyException;
23 import org.opensaml.ws.security.SecurityPolicyRule;
24 import org.opensaml.xml.util.DatatypeHelper;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28
29
30
31 public class MessageReplayRule implements SecurityPolicyRule {
32
33
34 private final Logger log = LoggerFactory.getLogger(MessageReplayRule.class);
35
36
37 private ReplayCache replayCache;
38
39
40 private boolean requiredRule;
41
42
43
44
45
46
47 public MessageReplayRule(ReplayCache newReplayCache) {
48 replayCache = newReplayCache;
49 requiredRule = true;
50 }
51
52
53
54
55
56
57 public boolean isRequiredRule() {
58 return requiredRule;
59 }
60
61
62
63
64
65
66 public void setRequiredRule(boolean required) {
67 requiredRule = required;
68 }
69
70
71 public void evaluate(MessageContext messageContext) throws SecurityPolicyException {
72 if (!(messageContext instanceof SAMLMessageContext)) {
73 log.debug("Invalid message context type, this policy rule only supports SAMLMessageContext");
74 return;
75 }
76
77 SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;
78
79 String messageIsuer = DatatypeHelper.safeTrimOrNullString(samlMsgCtx.getInboundMessageIssuer());
80 if (messageIsuer == null && requiredRule) {
81 log.warn("Message contained no Issuer ID, replay check not possible");
82 throw new SecurityPolicyException("Message contained no Issuer ID, replay check not possible");
83 }
84
85 String messageId = DatatypeHelper.safeTrimOrNullString(samlMsgCtx.getInboundSAMLMessageId());
86 if (messageId == null && requiredRule) {
87 log.error("Message contained no ID, replay check not possible");
88 throw new SecurityPolicyException("SAML message from issuer " + messageIsuer + " did not contain an ID");
89 }
90
91 if (replayCache.isReplay(messageIsuer, messageId)) {
92 log.warn("Replay detected of message '" + messageId + "' from issuer " + messageIsuer);
93 throw new SecurityPolicyException("Rejecting replayed message ID '" + messageId + "' from issuer "
94 + messageIsuer);
95 }
96
97 }
98 }