/**
  * Determines whether given AssertionConsumerService can be used to deliver messages consumable by
  * this profile. Bindings POST and Artifact are supported for WebSSO.
  *
  * @param endpoint endpoint
  * @return true if endpoint is supported
  * @throws MetadataProviderException in case system can't verify whether endpoint is supported or
  *     not
  */
 protected boolean isEndpointSupported(AssertionConsumerService endpoint)
     throws MetadataProviderException {
   return org.opensaml.common.xml.SAMLConstants.SAML2_POST_BINDING_URI.equals(
           endpoint.getBinding())
       | org.opensaml.common.xml.SAMLConstants.SAML2_ARTIFACT_BINDING_URI.equals(
           endpoint.getBinding());
 }
 /**
  * Fills the request with assertion consumer service url and protocol binding based on
  * assertionConsumer to be used to deliver response from the IDP.
  *
  * @param request request
  * @param service service to deliver response to, building is skipped when null
  * @throws MetadataProviderException error retrieving metadata information
  */
 protected void buildReturnAddress(AuthnRequest request, AssertionConsumerService service)
     throws MetadataProviderException {
   if (service != null) {
     // AssertionConsumerServiceURL + ProtocolBinding is mutually exclusive with
     // AssertionConsumerServiceIndex, we use the first one here
     if (service.getResponseLocation() != null) {
       request.setAssertionConsumerServiceURL(service.getResponseLocation());
     } else {
       request.setAssertionConsumerServiceURL(service.getLocation());
     }
     request.setProtocolBinding(getEndpointBinding(service));
   }
 }
  /**
   * Determines endpoint where should the identity provider return the SAML message. Endpoint also
   * implies the used binding. In case assertionConsumerIndex in the WebSSOProfileOptions is
   * specified the endpoint with the given ID is used. Otherwise assertionConsumerService marked as
   * default is used when present, otherwise first found supported assertionConsumerService is used.
   *
   * <p>In case endpoint determined by the webSSOProfileOptions index is not supported by the
   * profile an exception is raised.
   *
   * @param options user supplied preferences
   * @param idpSSODescriptor idp, can be null when no IDP is known in advance
   * @param spDescriptor sp
   * @return consumer service or null
   * @throws MetadataProviderException in case index supplied in options is invalid or unsupported
   *     or no supported consumer service can be found
   */
  protected AssertionConsumerService getAssertionConsumerService(
      WebSSOProfileOptions options, IDPSSODescriptor idpSSODescriptor, SPSSODescriptor spDescriptor)
      throws MetadataProviderException {

    List<AssertionConsumerService> services = spDescriptor.getAssertionConsumerServices();

    // Use user preference
    if (options.getAssertionConsumerIndex() != null) {
      for (AssertionConsumerService service : services) {
        if (options.getAssertionConsumerIndex().equals(service.getIndex())) {
          if (!isEndpointSupported(service)) {
            throw new MetadataProviderException(
                "Endpoint designated by the value in the WebSSOProfileOptions is not supported by this profile");
          } else {
            log.debug(
                "Using consumer service determined by user preference with binding {}",
                service.getBinding());
            return service;
          }
        }
      }
      throw new MetadataProviderException(
          "AssertionConsumerIndex "
              + options.getAssertionConsumerIndex()
              + " not found for spDescriptor "
              + spDescriptor);
    }

    // Use default
    if (spDescriptor.getDefaultAssertionConsumerService() != null
        && isEndpointSupported(spDescriptor.getDefaultAssertionConsumerService())) {
      AssertionConsumerService service = spDescriptor.getDefaultAssertionConsumerService();
      log.debug("Using default consumer service with binding {}", service.getBinding());
      log.debug("Default ACS url=" + service.getLocation());
      return service;
    }

    // Iterate and find first match
    if (services.size() > 0) {
      for (AssertionConsumerService service : services) {
        if (isEndpointSupported(service)) {
          log.debug("Using first available consumer service with binding {}", service.getBinding());
          return service;
        }
      }
    }

    throw new MetadataProviderException(
        "Service provider has no assertion consumer service available for the selected profile "
            + spDescriptor);
  }
Пример #4
0
  private void init(InputStream inputStream) throws SAMLException {
    BasicParserPool parsers = new BasicParserPool();
    parsers.setNamespaceAware(true);

    EntityDescriptor edesc;

    try {
      Document doc = parsers.parse(inputStream);
      Element root = doc.getDocumentElement();

      UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();

      edesc = (EntityDescriptor) unmarshallerFactory.getUnmarshaller(root).unmarshall(root);
    } catch (org.opensaml.xml.parse.XMLParserException e) {
      throw new SAMLException(e);
    } catch (org.opensaml.xml.io.UnmarshallingException e) {
      throw new SAMLException(e);
    }

    // fetch sp information
    SPSSODescriptor spDesc = edesc.getSPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol");

    if (spDesc == null) throw new SAMLException("No SP SSO descriptor found");

    // get first redirect or post binding
    String acsUrl = null;
    for (AssertionConsumerService svc : spDesc.getAssertionConsumerServices()) {
      if (svc.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)
          || svc.getBinding().equals(SAMLConstants.SAML2_POST_BINDING_URI)) {
        acsUrl = svc.getLocation();
        break;
      }
    }

    if (acsUrl == null) throw new SAMLException("No acceptable Assertion Consumer Service found");

    this.setEntityId(edesc.getEntityID());
    this.setAcs(acsUrl);
  }