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.idp.profile.saml1;
19  
20  import java.util.List;
21  
22  import org.opensaml.common.binding.BasicEndpointSelector;
23  import org.opensaml.saml2.metadata.Endpoint;
24  import org.opensaml.xml.util.DatatypeHelper;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  /**
29   * An endpoint selector that may optionally take a SP-provided assertion consumer service URL, validate it against
30   * metadata, and return an endpoint based on it. If no URL is provided the {@link BasicEndpointSelector} selection is
31   * used.
32   */
33  public class ShibbolethSSOEndpointSelector extends BasicEndpointSelector {
34  
35      /** Class logger. */
36      private final Logger log = LoggerFactory.getLogger(ShibbolethSSOEndpointSelector.class);
37  
38      /** Assertion consumer service URL provided by SP. */
39      private String spAssertionConsumerService;
40  
41      /**
42       * Gets the assertion consumer service URL provided by SP.
43       * 
44       * @return assertion consumer service URL provided by SP
45       */
46      public String getSpAssertionConsumerService() {
47          return spAssertionConsumerService;
48      }
49  
50      /**
51       * Sets the assertion consumer service URL provided by SP.
52       * 
53       * @param acs assertion consumer service URL provided by SP
54       */
55      public void setSpAssertionConsumerService(String acs) {
56          spAssertionConsumerService = DatatypeHelper.safeTrimOrNullString(acs);
57      }
58  
59      /** {@inheritDoc} */
60      public Endpoint selectEndpoint() {
61          if (getEntityRoleMetadata() == null) {
62              log.debug("Unable to select endpoint, no entity role metadata available.");
63              return null;
64          }
65  
66          if (spAssertionConsumerService != null) {
67              return selectEndpointByACS();
68          } else {
69              return super.selectEndpoint();
70          }
71      }
72  
73      /**
74       * Selects the endpoint, from metadata, corresponding to the SP-provdided ACS URL.
75       * 
76       * @return endpoint corresponding to the SP-provdided ACS URL
77       */
78      protected Endpoint selectEndpointByACS() {
79          log.debug("Selecting endpoint from metadata corresponding to provided ACS URL: '{}'",
80                  getSpAssertionConsumerService());
81  
82          List<Endpoint> endpoints = getEntityRoleMetadata().getEndpoints();
83          log.debug("Relying party role contains '{}' endpoints", endpoints.size());
84  
85          if (endpoints != null && endpoints.size() > 0) {
86              for (Endpoint endpoint : endpoints) {
87                  if (endpoint == null || !getSupportedIssuerBindings().contains(endpoint.getBinding())) {
88                      continue;
89                  }
90  
91                  if (endpoint.getLocation().equalsIgnoreCase(spAssertionConsumerService)) {
92                      return endpoint;
93                  }
94  
95                  if (!DatatypeHelper.isEmpty(endpoint.getResponseLocation())
96                          && endpoint.getResponseLocation().equalsIgnoreCase(spAssertionConsumerService)) {
97                      return endpoint;
98                  }
99              }
100         }
101 
102         log.debug("No endpoint meets selection criteria for SAML entity '{}'", getEntityMetadata().getEntityID());
103         return null;
104     }
105 }