View Javadoc

1   /*
2    * Licensed to the University Corporation for Advanced Internet Development, 
3    * Inc. (UCAID) under one or more contributor license agreements.  See the 
4    * NOTICE file distributed with this work for additional information regarding
5    * copyright ownership. The UCAID licenses this file to You under the Apache 
6    * License, Version 2.0 (the "License"); you may not use this file except in 
7    * compliance with the License.  You may obtain a copy of the License at
8    *
9    *    http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.principalConnector;
19  
20  import org.opensaml.common.SAMLObject;
21  import org.opensaml.saml1.core.NameIdentifier;
22  import org.opensaml.saml2.core.NameID;
23  import org.opensaml.util.storage.StorageService;
24  
25  import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
26  import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ShibbolethResolutionContext;
27  import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.attributeDefinition.TransientIdEntry;
28  import edu.internet2.middleware.shibboleth.common.profile.provider.SAMLProfileRequestContext;
29  
30  /**
31   * A principal connector that attempts to look up a name identifier within a store.
32   */
33  public class TransientPrincipalConnector extends BasePrincipalConnector {
34  
35      /** Store used to map transient identifier tokens to principal names. */
36      private StorageService<String, TransientIdEntry> identifierStore;
37  
38      /** Storage partition in which IDs are stored. */
39      private String partition;
40  
41      /**
42       * Constructor.
43       * 
44       * @param store the backing store used to map transient identifier tokens to principal names
45       */
46      public TransientPrincipalConnector(StorageService<String, TransientIdEntry> store) {
47          if (store == null) {
48              throw new IllegalArgumentException("Identifier store may not be null");
49          }
50          identifierStore = store;
51          partition = "transientId";
52      }
53  
54      /** {@inheritDoc} */
55      public String resolve(ShibbolethResolutionContext resolutionContext) throws AttributeResolutionException {
56          SAMLProfileRequestContext requestContext = resolutionContext.getAttributeRequestContext();
57  
58          String transientId = null;
59          SAMLObject subjectId = requestContext.getSubjectNameIdentifier();
60          if (subjectId instanceof NameIdentifier) {
61              NameIdentifier nameId = (NameIdentifier) requestContext.getSubjectNameIdentifier();
62              if (nameId != null) {
63                  transientId = nameId.getNameIdentifier();
64              }
65          } else if (requestContext.getSubjectNameIdentifier() instanceof NameID) {
66              NameID nameId = (NameID) requestContext.getSubjectNameIdentifier();
67              if (nameId != null) {
68                  transientId = nameId.getValue();
69              }
70          } else {
71              throw new AttributeResolutionException("Subject name identifier is not of a supported type");
72          }
73  
74          if (transientId == null) {
75              throw new AttributeResolutionException("Invalid subject name identifier");
76          }
77  
78          TransientIdEntry idToken = identifierStore.get(partition, transientId);
79          if (idToken == null || idToken.isExpired()) {
80              throw new AttributeResolutionException("No information associated with transient identifier: "
81                      + transientId);
82          }
83  
84          if (!idToken.getRelyingPartyId().equals(requestContext.getInboundMessageIssuer())) {
85              throw new AttributeResolutionException("Transient identifier was issued to " + idToken.getRelyingPartyId()
86                      + " but is being used by " + requestContext.getInboundMessageIssuer());
87          }
88  
89          return idToken.getPrincipalName();
90      }
91  
92      /** {@inheritDoc} */
93      public void validate() throws AttributeResolutionException {
94  
95      }
96  }