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