/**
  * Constructor.
  *
  * @param extensionSchemas classpath location of metadata extension schemas, may be null
  */
 public SchemaValidationFilter(String[] extensionSchemas) {
   if (extensionSchemas != null) {
     for (String extension : extensionSchemas) {
       extension = DatatypeHelper.safeTrimOrNullString(extension);
       if (extension != null) {
         SAMLSchemaBuilder.addExtensionSchema(extension);
       }
     }
   }
 }
  /** {@inheritDoc} */
  public void doFilter(XMLObject metadata) throws FilterException {
    Validator schemaValidator = null;
    try {
      schemaValidator = SAMLSchemaBuilder.getSAML11Schema().newValidator();
    } catch (SAXException e) {
      log.error("Unable to build metadata validation schema", e);
      throw new FilterException("Unable to build metadata validation schema", e);
    }

    try {
      schemaValidator.validate(new DOMSource(metadata.getDOM()));
    } catch (Exception e) {
      log.error("Incoming metadata was not schema valid.", e);
      throw new FilterException("Incoming metadata was not schema valid.", e);
    }
  }
  /**
   * 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;
  }