1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.attributeDefinition;
19
20 import java.security.NoSuchAlgorithmException;
21
22 import org.opensaml.common.IdentifierGenerator;
23 import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
24 import org.opensaml.util.storage.StorageService;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
29 import edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute;
30 import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
31 import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ShibbolethResolutionContext;
32 import edu.internet2.middleware.shibboleth.common.profile.provider.SAMLProfileRequestContext;
33
34
35
36
37
38
39
40
41 public class TransientIdAttributeDefinition extends BaseAttributeDefinition {
42
43
44 private final Logger log = LoggerFactory.getLogger(TransientIdAttributeDefinition.class);
45
46
47 private StorageService<String, TransientIdEntry> idStore;
48
49
50 private String partition;
51
52
53 private IdentifierGenerator idGenerator;
54
55
56 private int idSize;
57
58
59 private long idLifetime;
60
61
62
63
64
65
66
67
68
69 public TransientIdAttributeDefinition(StorageService<String, TransientIdEntry> store)
70 throws NoSuchAlgorithmException {
71 idGenerator = new SecureRandomIdentifierGenerator();
72 idStore = store;
73 partition = "transientId";
74 idSize = 16;
75 idLifetime = 1000 * 60 * 60 * 4;
76
77
78 idGenerator.generateIdentifier(idSize);
79 }
80
81
82 protected BaseAttribute doResolve(ShibbolethResolutionContext resolutionContext)
83 throws AttributeResolutionException {
84
85 BasicAttribute<String> attribute = new BasicAttribute<String>();
86 attribute.setId(getId());
87
88 SAMLProfileRequestContext requestContext = resolutionContext.getAttributeRequestContext();
89
90 String principalName = requestContext.getPrincipalName();
91 if (principalName == null) {
92 log.debug("Principal name for request {} was null, no attribute returned",
93 requestContext.getInboundSAMLMessageId());
94 return attribute;
95 }
96
97 log.debug(
98 "Building transient ID for request {}; outbound message issuer: {}, inbound message issuer: {}, principal identifer: {}",
99 new Object[] { requestContext.getInboundSAMLMessageId(), requestContext.getOutboundMessageIssuer(),
100 requestContext.getInboundMessageIssuer(), principalName, });
101 StringBuilder principalTokenIdBuilder = new StringBuilder();
102 principalTokenIdBuilder.append(requestContext.getOutboundMessageIssuer()).append("!")
103 .append(requestContext.getInboundMessageIssuer()).append("!").append(principalName);
104 String principalTokenId = principalTokenIdBuilder.toString();
105
106 TransientIdEntry tokenEntry = idStore.get(partition, principalTokenId);
107 if (tokenEntry == null || tokenEntry.isExpired()) {
108 String token = idGenerator.generateIdentifier(idSize);
109 tokenEntry = new TransientIdEntry(idLifetime, requestContext.getInboundMessageIssuer(), principalName,
110 token);
111 idStore.put(partition, token, tokenEntry);
112 idStore.put(partition, principalTokenId, tokenEntry);
113 }
114
115 log.debug("Created transient ID {} for request {}", tokenEntry.getId(),
116 requestContext.getInboundSAMLMessageId());
117 attribute.getValues().add(tokenEntry.getId());
118
119 return attribute;
120 }
121
122
123
124
125
126
127 public int getIdSize() {
128 return idSize;
129 }
130
131
132
133
134
135
136 public void setIdSize(int size) {
137 idSize = size;
138 }
139
140
141
142
143
144
145 public long getIdLifetime() {
146 return idLifetime;
147 }
148
149
150
151
152
153
154 public void setTokenLiftetime(long lifetime) {
155 idLifetime = lifetime;
156 }
157
158
159 public void validate() throws AttributeResolutionException {
160
161 }
162 }