View Javadoc

1   /*
2    * Copyright 2007 University Corporation for Advanced Internet Development, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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  
25  import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
26  import edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute;
27  import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
28  import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ShibbolethResolutionContext;
29  import edu.internet2.middleware.shibboleth.common.profile.provider.SAMLProfileRequestContext;
30  
31  /**
32   * An attribute definition that generates random identifiers useful for transient subject IDs.
33   * 
34   * Information about the created IDs are stored within a provided {@link StorageService} in the form of {@link TransientIdEntry}s.
35   * Each entry is mapped under two keys; the generated ID and a key derived from the tuple (outbound message issuer,
36   * inbound message issuer, principal name).
37   */
38  public class TransientIdAttributeDefinition extends BaseAttributeDefinition {
39  
40      /** Store used to map tokens to principals. */
41      private StorageService<String, TransientIdEntry> idStore;
42  
43      /** Storage partition in which IDs are stored. */
44      private String partition;
45  
46      /** Generator of random, hex-encoded, tokens. */
47      private IdentifierGenerator idGenerator;
48  
49      /** Size, in bytes, of the token. */
50      private int idSize;
51  
52      /** Length, in milliseconds, tokens are valid. */
53      private long idLifetime;
54  
55      /**
56       * Constructor.
57       * 
58       * @param store store used to map tokens to principals
59       * 
60       * @throws NoSuchAlgorithmException thrown if the SHA1PRNG, used as the default random number generation algorithm,
61       *             is not supported
62       */
63      public TransientIdAttributeDefinition(StorageService<String, TransientIdEntry> store) throws NoSuchAlgorithmException {
64          idGenerator = new SecureRandomIdentifierGenerator();
65          idStore = store;
66          partition = "transientId";
67          idSize = 16;
68          idLifetime = 1000 * 60 * 60 * 4;
69  
70          // Prime the generator
71          idGenerator.generateIdentifier(idSize);
72      }
73  
74      /** {@inheritDoc} */
75      protected BaseAttribute doResolve(ShibbolethResolutionContext resolutionContext)
76              throws AttributeResolutionException {
77  
78          SAMLProfileRequestContext requestContext = resolutionContext.getAttributeRequestContext();
79  
80          StringBuilder principalTokenIdBuilder = new StringBuilder();
81          principalTokenIdBuilder.append(requestContext.getOutboundMessageIssuer()).append("!").append(
82                  requestContext.getInboundMessageIssuer()).append("!").append(requestContext.getPrincipalName());
83          String principalTokenId = principalTokenIdBuilder.toString();
84  
85          TransientIdEntry tokenEntry = idStore.get(partition, principalTokenId);
86          if (tokenEntry == null || tokenEntry.isExpired()) {
87              String token = idGenerator.generateIdentifier(idSize);
88              tokenEntry = new TransientIdEntry(idLifetime, requestContext.getInboundMessageIssuer(), requestContext
89                      .getPrincipalName(), token);
90              idStore.put(partition, token, tokenEntry);
91              idStore.put(partition, principalTokenId, tokenEntry);
92          }
93  
94          BasicAttribute<String> attribute = new BasicAttribute<String>();
95          attribute.setId(getId());
96          attribute.getValues().add(tokenEntry.getId());
97  
98          return attribute;
99      }
100 
101     /**
102      * Gets the size, in bytes, of the id.
103      * 
104      * @return size, in bytes, of the id
105      */
106     public int getIdSize() {
107         return idSize;
108     }
109 
110     /**
111      * Sets the size, in bytes, of the id.
112      * 
113      * @param size size, in bytes, of the id
114      */
115     public void setIdSize(int size) {
116         idSize = size;
117     }
118 
119     /**
120      * Gets the time, in milliseconds, ids are valid.
121      * 
122      * @return time, in milliseconds, ids are valid
123      */
124     public long getIdLifetime() {
125         return idLifetime;
126     }
127 
128     /**
129      * Sets the time, in milliseconds, ids are valid.
130      * 
131      * @param lifetime time, in milliseconds, ids are valid
132      */
133     public void setTokenLiftetime(long lifetime) {
134         idLifetime = lifetime;
135     }
136 
137     /** {@inheritDoc} */
138     public void validate() throws AttributeResolutionException {
139 
140     }
141 }