private MetadataProvider getMetadataProvider() throws MetadataProviderException {
    if (logger.isDebugEnabled()) {
      logger.debug("getMetadataProvider() - start"); // $NON-NLS-1$
    }

    org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider provider =
        new FilesystemMetadataProvider(new File(metadataProvider));
    BasicParserPool bpp = new BasicParserPool();
    bpp.setNamespaceAware(true);
    provider.setParserPool(bpp);

    if (logger.isDebugEnabled()) {
      logger.debug("getMetadataProvider() - end"); // $NON-NLS-1$
    }
    return provider;
  }
Beispiel #2
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);
  }
  /**
   * Returns AuthnRequest SAML message to be used to demand authentication from an IDP described
   * using idpEntityDescriptor, with an expected response to the assertionConsumer address.
   *
   * @param context message context
   * @param options preferences of message creation
   * @param assertionConsumer assertion consumer where the IDP should respond
   * @param bindingService service used to deliver the request
   * @return authnRequest ready to be sent to IDP
   * @throws SAMLException error creating the message
   * @throws MetadataProviderException error retreiving metadata
   */
  protected AuthnRequest getAuthnRequest(
      SAMLMessageContext context,
      WebSSOProfileOptions options,
      AssertionConsumerService assertionConsumer,
      SingleSignOnService bindingService)
      throws SAMLException, MetadataProviderException {

    SAMLObjectBuilder<AuthnRequest> builder =
        (SAMLObjectBuilder<AuthnRequest>)
            builderFactory.getBuilder(AuthnRequest.DEFAULT_ELEMENT_NAME);
    AuthnRequest request = builder.buildObject();

    request.setIsPassive(options.getPassive());
    request.setForceAuthn(options.getForceAuthN());
    request.setProviderName(options.getProviderName());
    request.setVersion(SAMLVersion.VERSION_20);
    if (options.getIncludeEidas()) {
      // ne sert à rien
      //            request.setAssertionConsumerServiceURL(options.getIssuer());
      //            IssuerBuilder issuerBuilder = new IssuerBuilder();
      //            Issuer issuer = issuerBuilder.buildObject();
      //            issuer.setFormat(NAME_ISSUER_FORMAT_EIDAS);
      //            log.debug("issuer="+options.getIssuer());
      //            issuer.setValue(options.getIssuer());
      //            request.setIssuer(issuer);
      NameIDPolicy nameIDPolicy = new NameIDPolicyBuilder().buildObject();
      nameIDPolicy.setFormat(NAME_POLICY_FORMAT_EIDAS);
      nameIDPolicy.setAllowCreate(true);
      request.setNameIDPolicy(nameIDPolicy);
      QName eidas = new QName("xmlns:eidas", "http://eidas.europa.eu/saml-extensions");
      request.getNamespaceManager().registerAttributeName(eidas);
      Extensions extEidas =
          new ExtensionsBuilder()
              .buildObject("urn:oasis:names:tc:SAML:2.0:protocol", "Extensions", "saml2p");
      // Extensions extEidas = new EidasExtensions();
      Collection<String> colAttr = options.getEidasAttributes();
      // XSAnyBuilder raBuild = new XSAnyBuilder();
      // <eidas:SPType>public</eidas:SPType>
      SPType pub =
          new SPTypeBuilder()
              .buildObject("http://eidas.europa.eu/saml-extensions", "SPType", "eidas");
      // pub.setTextContent(EIDAS_PUBLIC);
      pub.setSPType(EIDAS_PUBLIC);
      // XSAny attrs = new XSAnyBuilder().buildObject("http://eidas.europa.eu/saml-extensions",
      // "RequestedAttributes", "eidas");
      extEidas.getUnknownXMLObjects().add(pub);
      // XSAnyBuilder anyBuilder = (XSAnyBuilder)
      // Configuration.getBuilderFactory().getBuilder(XSAny.TYPE_NAME);
      String resAttrs =
          "<eidas:RequestedAttributes xmlns:eidas=\"http://eidas.europa.eu/saml-extensions\">";
      for (String attr : colAttr) {
        resAttrs += oneAttribute(attr);
      }
      resAttrs += "</eidas:RequestedAttributes>";
      log.debug("resAttrs=" + resAttrs);
      EidasExtensionConfiguration eidasExt = new EidasExtensionConfiguration();
      eidasExt.configureExtension();
      SAMLSchemaBuilder.addExtensionSchema("/schema/saml_eidas_extension.xsd");
      BasicParserPool ppMgr = new BasicParserPool();
      ppMgr.setNamespaceAware(true);
      try {
        ppMgr.setSchema(SAMLSchemaBuilder.getSAML11Schema());
      } catch (SAXException ex) {
        log.error("Erreur schema=" + ex);
        return null;
      }
      InputStream is = new ByteArrayInputStream(resAttrs.getBytes());
      Document domAttrsRaq = null;
      try {
        domAttrsRaq = ppMgr.parse(is);
      } catch (XMLParserException e) {
        log.error("Erreur dom=" + e);
        return null;
      }
      if (domAttrsRaq == null) {
        log.error("Erreur dom vide");
        return null;
      }
      RequestedAttributesUnmarshaller unMars = new RequestedAttributesUnmarshaller();
      XMLObject attrs = null;
      try {
        attrs = unMars.unmarshall(domAttrsRaq.getDocumentElement());
      } catch (UnmarshallingException e) {
        System.err.println("Erreur unMarsh error=" + e);
      }

      extEidas.getUnknownXMLObjects().add(attrs);
      request.setExtensions(extEidas);
    }
    buildCommonAttributes(context.getLocalEntityId(), request, bindingService);

    buildScoping(request, bindingService, options);
    builNameIDPolicy(request, options);
    buildAuthnContext(request, options);
    buildReturnAddress(request, assertionConsumer);

    return request;
  }
  /**
   * @param SAMLToken - SAML Assertion XML
   * @param contextAttributeName - SAML Attribute name containing Context data
   * @param verfiySignature
   * @return a base64 encoded string containing the context
   * @throws SAMLValidationException - if validation fails
   */
  public static List<AttributeStatement> validate(byte[] SAMLToken, SAMLConfiguration samlConfig)
      throws SAMLValidationException {
    if (logger.isDebugEnabled()) {
      logger.debug("validate(byte[], SAMLConfiguration) - start"); // $NON-NLS-1$
    }

    Decrypter samlDecrypter = samlConfig.getSamlDecrypter();
    SignatureTrustEngine sigTrustEngine = samlConfig.getTrustEngine();
    String myURI = samlConfig.getMyURI();
    MessageReplayRule replayRule = samlConfig.getReplayRule();

    BasicParserPool ppMgr = new BasicParserPool();
    ppMgr.setNamespaceAware(true);

    VerifySignatureType verfiySignature = samlConfig.getVerifySignature();

    List<AttributeStatement> attrStatements = null;
    if (SAMLToken != null) {
      try {

        InputStream in = new ByteArrayInputStream(SAMLToken);
        Document SAMLDoc;
        try {
          SAMLDoc = ppMgr.parse(in);
        } catch (XMLParserException e) {
          logger.error(
              "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType)",
              e); //$NON-NLS-1$

          throw createSAMLValidationException("Error parsing SAML XML", true, e);
        }
        Element responseElement = SAMLDoc.getDocumentElement();

        SAMLType samlType = SAMLType.Response;
        if (responseElement == null) {
          throw createSAMLValidationException(
              "Missing SAML Encrypted Assertion or Assertion or Assertion Response", true);
        }
        if (!"Response".equals(responseElement.getLocalName())
            || !SAMLConstants.SAML20P_NS.equals(responseElement.getNamespaceURI())) {
          if (!"Assertion".equals(responseElement.getLocalName())
              || !SAMLConstants.SAML20_NS.equals(responseElement.getNamespaceURI())) {
            if (!"EncryptedAssertion".equals(responseElement.getLocalName())
                || !SAMLConstants.SAML20_NS.equals(responseElement.getNamespaceURI())) {
              throw createSAMLValidationException(
                  "Missing or invalid SAML Encrypted Assertion or Assertion or Assertion Response",
                  true);
            } else {
              samlType = SAMLType.EncryptedAssertion;
            }
          } else {
            samlType = SAMLType.Assertion;
          }
        } else {
          samlType = SAMLType.Response;
        }

        if (samlType == SAMLType.Response) {
          // Unmarshall SAML Assertion Response into an OpenSAML Java object.
          UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
          Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(responseElement);
          Response samlResponse;
          try {
            samlResponse = (Response) unmarshaller.unmarshall(responseElement);
          } catch (UnmarshallingException e) {
            logger.error(
                "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType)",
                e); //$NON-NLS-1$

            throw createSAMLValidationException(
                "Error in unmarshalling SAML XML Document", true, e);
          }

          // Check the replay attack for Response
          if (replayRule != null) {
            BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext();
            // messageContext.setInboundMessage(samlResponse);
            if (samlResponse.getIssuer() != null)
              messageContext.setInboundMessageIssuer(samlResponse.getIssuer().getValue());
            messageContext.setInboundSAMLMessageId(samlResponse.getID());

            try {
              replayRule.evaluate(messageContext);
            } catch (SecurityPolicyException e) {
              logger.error(
                  "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType)",
                  e); //$NON-NLS-1$

              throw createSAMLValidationException("Possible Replay Attack for Response", false, e);
            }
          }

          // Validate the status code
          if (!StatusCode.SUCCESS_URI.equals(samlResponse.getStatus().getStatusCode().getValue())) {
            throw createSAMLValidationException("Invalid Status Code.", true);
          }

          boolean responseSignatureVerified =
              validateResponseSignature(samlResponse, sigTrustEngine, verfiySignature);

          // Get first encrypted Assertion, if not present get first unencrypted assertion
          int assertCount = samlResponse.getEncryptedAssertions().size();
          if (assertCount == 0) {
            assertCount = samlResponse.getAssertions().size();
            if (assertCount == 0) {
              throw createSAMLValidationException(
                  "No Assertion or EncryptedAssertion found in received response", true);
            } else {
              for (Assertion samlAssertion : samlResponse.getAssertions()) {
                attrStatements =
                    validateAssertion(
                        samlAssertion,
                        sigTrustEngine,
                        myURI,
                        replayRule,
                        verfiySignature,
                        responseSignatureVerified);
                break; // Use the first only
              }
            }
          } else {
            for (EncryptedAssertion samlEncryptedAssertion :
                samlResponse.getEncryptedAssertions()) {

              // Decryption

              Assertion samlAssertion = null;
              try {
                samlAssertion = samlDecrypter.decrypt(samlEncryptedAssertion);
              } catch (DecryptionException e) {
                logger.error(
                    "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType)",
                    e); //$NON-NLS-1$

                throw createSAMLValidationException(
                    "Error Decrypting Received Encrypted Assertion", true, e);
              }
              attrStatements =
                  validateAssertion(
                      samlAssertion,
                      sigTrustEngine,
                      myURI,
                      replayRule,
                      verfiySignature,
                      responseSignatureVerified);

              break; // Use the first only
            }
          }
        } else if (samlType == SAMLType.EncryptedAssertion) {
          // Unmarshall SAML Encrypted Assertion into an OpenSAML Java object.
          UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
          Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(responseElement);
          EncryptedAssertion encryptedAssertion = null;
          try {
            encryptedAssertion = (EncryptedAssertion) unmarshaller.unmarshall(responseElement);
          } catch (UnmarshallingException e) {
            logger.error(
                "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType)",
                e); //$NON-NLS-1$

            throw createSAMLValidationException(
                "Error in unmarshalling SAML XML Document", true, e);
          }

          boolean responseSignatureVerified = false;

          // Decryption

          Assertion samlAssertion = null;
          try {
            samlAssertion = samlDecrypter.decrypt(encryptedAssertion);
          } catch (DecryptionException e) {
            logger.error(
                "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType)",
                e); //$NON-NLS-1$

            throw createSAMLValidationException(
                "Error Decrypting Received Encrypted Assertion", true, e);
          }

          attrStatements =
              validateAssertion(
                  samlAssertion,
                  sigTrustEngine,
                  myURI,
                  replayRule,
                  verfiySignature,
                  responseSignatureVerified);
        } else if (samlType == SAMLType.Assertion) {
          // Unmarshall SAML Assertion  into an OpenSAML Java object.
          UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
          Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(responseElement);
          Assertion samlAssertion = null;
          try {
            samlAssertion = (Assertion) unmarshaller.unmarshall(responseElement);
          } catch (UnmarshallingException e) {
            logger.error(
                "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType)",
                e); //$NON-NLS-1$

            throw createSAMLValidationException(
                "Error in unmarshalling SAML XML Document", true, e);
          }

          boolean responseSignatureVerified = false;

          attrStatements =
              validateAssertion(
                  samlAssertion,
                  sigTrustEngine,
                  myURI,
                  replayRule,
                  verfiySignature,
                  responseSignatureVerified);
        }
      } catch (SAMLValidationException e) {
        throw e;
      }
    }

    if (logger.isDebugEnabled()) {
      logger.debug(
          "validate(byte[], String, Decrypter, SignatureTrustEngine, String, MessageReplayRule, ParserPool, VerifySignatureType) - end"); //$NON-NLS-1$
    }
    return attrStatements;
  }