/**
  * Serializes the specified SAML 2.0 based XML content representation to its corresponding actual
  * XML syntax representation.
  *
  * @param xmlObject the SAML 2.0 based XML content object
  * @return a {@link String} representation of the actual XML representation of the SAML 2.0 based
  *     XML content representation
  * @throws SSOException if an error occurs during the marshalling process
  */
 public static String marshall(XMLObject xmlObject) throws SSOException {
   try {
     //  Explicitly sets the special XML parser library to be used, in the global variables
     System.setProperty(
         "javax.xml.parsers.DocumentBuilderFactory",
         "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
     MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory();
     Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject);
     Element element = marshaller.marshall(xmlObject);
     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
     DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
     DOMImplementationLS implementation =
         (DOMImplementationLS) registry.getDOMImplementation("LS");
     LSSerializer writer = implementation.createLSSerializer();
     LSOutput output = implementation.createLSOutput();
     output.setByteStream(byteArrayOutputStream);
     writer.write(element, output);
     return new String(byteArrayOutputStream.toByteArray(), Charset.forName("UTF-8"));
   } catch (ClassNotFoundException
       | InstantiationException
       | MarshallingException
       | IllegalAccessException e) {
     throw new SSOException("Error in marshalling SAML2 Assertion", e);
   }
 }
  private XMLObject unmarshall(String samlString) throws SAMLSSOException {

    try {
      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
      documentBuilderFactory.setNamespaceAware(true);
      documentBuilderFactory.setExpandEntityReferences(false);
      documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
      org.apache.xerces.util.SecurityManager securityManager = new SecurityManager();
      securityManager.setEntityExpansionLimit(ENTITY_EXPANSION_LIMIT);
      documentBuilderFactory.setAttribute(SECURITY_MANAGER_PROPERTY, securityManager);

      DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
      docBuilder.setEntityResolver(new CarbonEntityResolver());
      ByteArrayInputStream is = new ByteArrayInputStream(samlString.getBytes());
      Document document = docBuilder.parse(is);
      Element element = document.getDocumentElement();
      UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
      Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
      return unmarshaller.unmarshall(element);
    } catch (ParserConfigurationException e) {
      throw new SAMLSSOException("Error in unmarshalling SAML Request from the encoded String", e);
    } catch (UnmarshallingException e) {
      throw new SAMLSSOException("Error in unmarshalling SAML Request from the encoded String", e);
    } catch (SAXException e) {
      throw new SAMLSSOException("Error in unmarshalling SAML Request from the encoded String", e);
    } catch (IOException e) {
      throw new SAMLSSOException("Error in unmarshalling SAML Request from the encoded String", e);
    }
  }
 /**
  * Serializes an authentication request into a string.
  *
  * @param request the request to serialize
  * @return the serialized form of the string
  * @throws MarshallingException thrown if the request can not be marshalled and serialized
  */
 protected String serializeRequest(AuthnRequest request) throws MarshallingException {
   Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(request);
   Element requestElem = marshaller.marshall(request);
   StringWriter writer = new StringWriter();
   XMLHelper.writeNode(requestElem, writer);
   return writer.toString();
 }
 @BeforeClass
 public static void initializeOpenSAML() throws Exception {
   DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
   System.out.println(newFactory.getClass().getName());
   DefaultBootstrap.bootstrap();
   builderFactory = Configuration.getBuilderFactory();
 }
  /** {@inheritDoc} */
  protected void marshallAttributes(XMLObject samlObject, Element domElement)
      throws MarshallingException {
    RequestAbstractType req = (RequestAbstractType) samlObject;

    if (req.getVersion() != null) {
      domElement.setAttributeNS(
          null, RequestAbstractType.VERSION_ATTRIB_NAME, req.getVersion().toString());
    }

    if (req.getID() != null) {
      domElement.setAttributeNS(null, RequestAbstractType.ID_ATTRIB_NAME, req.getID());
      domElement.setIdAttributeNS(null, RequestAbstractType.ID_ATTRIB_NAME, true);
    }

    if (req.getVersion() != null) {
      domElement.setAttributeNS(
          null, RequestAbstractType.VERSION_ATTRIB_NAME, req.getVersion().toString());
    }

    if (req.getIssueInstant() != null) {
      String iiStr = Configuration.getSAMLDateFormatter().print(req.getIssueInstant());
      domElement.setAttributeNS(null, RequestAbstractType.ISSUE_INSTANT_ATTRIB_NAME, iiStr);
    }

    if (req.getDestination() != null) {
      domElement.setAttributeNS(
          null, RequestAbstractType.DESTINATION_ATTRIB_NAME, req.getDestination());
    }

    if (req.getConsent() != null) {
      domElement.setAttributeNS(null, RequestAbstractType.CONSENT_ATTRIB_NAME, req.getConsent());
    }
  }
  /**
   * Gets the authentication request object.
   *
   * @return the authentication request object
   * @throws UnmarshallingException thrown if there is a problem unmarshalling the serialized form
   *     of the request
   */
  public synchronized AuthnRequest getAuthenticiationRequestXmlObject()
      throws UnmarshallingException {
    if (authnRequest == null) {
      try {
        ParserPool parser = Configuration.getParserPool();
        Document requestDoc = parser.parse(new StringReader(serialAuthnRequest));
        Unmarshaller requestUnmarshaller =
            Configuration.getUnmarshallerFactory().getUnmarshaller(AuthnRequest.TYPE_NAME);
        authnRequest =
            (AuthnRequest) requestUnmarshaller.unmarshall(requestDoc.getDocumentElement());
      } catch (XMLParserException e) {
        throw new UnmarshallingException(
            "Unable to unmarshall serialized authentication request", e);
      }
    }

    return authnRequest;
  }
  /** {@inheritDoc} */
  protected void marshallAttributes(XMLObject samlObject, Element domElement)
      throws MarshallingException {
    AuthnStatement authnStatement = (AuthnStatement) samlObject;

    if (authnStatement.getAuthnInstant() != null) {
      String authnInstantStr =
          Configuration.getSAMLDateFormatter().print(authnStatement.getAuthnInstant());
      domElement.setAttributeNS(null, AuthnStatement.AUTHN_INSTANT_ATTRIB_NAME, authnInstantStr);
    }

    if (authnStatement.getSessionIndex() != null) {
      domElement.setAttributeNS(
          null, AuthnStatement.SESSION_INDEX_ATTRIB_NAME, authnStatement.getSessionIndex());
    }

    if (authnStatement.getSessionNotOnOrAfter() != null) {
      String sessionNotOnOrAfterStr =
          Configuration.getSAMLDateFormatter().print(authnStatement.getSessionNotOnOrAfter());
      domElement.setAttributeNS(
          null, AuthnStatement.SESSION_NOT_ON_OR_AFTER_ATTRIB_NAME, sessionNotOnOrAfterStr);
    }
  }
Beispiel #8
0
 /**
  * Constructing the XMLObject Object from a String
  *
  * @param authReqStr
  * @return Corresponding XMLObject which is a SAML2 object
  * @throws Exception
  */
 public static XMLObject unmarshall(String authReqStr) throws Exception {
   try {
     doBootstrap();
     DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
     documentBuilderFactory.setNamespaceAware(true);
     DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
     Document document = docBuilder.parse(new ByteArrayInputStream(authReqStr.trim().getBytes()));
     Element element = document.getDocumentElement();
     UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
     Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
     return unmarshaller.unmarshall(element);
   } catch (Exception e) {
     throw new Exception("Error in constructing AuthRequest from " + "the encoded String ", e);
   }
 }
 /**
  * Returns a SAML 2.0 based XML content representation from the {@code String} value representing
  * the XML syntax.
  *
  * @param xmlString the {@link String} representation of the XML content
  * @return an XML object from the {@link String} value representing the XML syntax
  * @throws SSOException if an error occurs when unmarshalling the XML string representation
  */
 public static XMLObject unmarshall(String xmlString) throws SSOException {
   doBootstrap();
   try {
     DocumentBuilder docBuilder =
         SSOUtils.getDocumentBuilder(false, true, Optional.of(new XMLEntityResolver()));
     ByteArrayInputStream inputStream =
         new ByteArrayInputStream(xmlString.getBytes(Charset.forName("UTF-8")));
     Document document = docBuilder.parse(inputStream);
     Element element = document.getDocumentElement();
     UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
     Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
     return unmarshaller.unmarshall(element);
   } catch (UnmarshallingException | SAXException | IOException e) {
     throw new SSOException("Error in unmarshalling the XML string representation", e);
   }
 }
  /**
   * Encodes the SAML 2.0 based request XML object into its corresponding Base64 notation, based on
   * the type of SAML 2.0 binding.
   *
   * @param requestMessage the {@link RequestAbstractType} XML object to be encoded
   * @param binding the SAML 2.0 binding type
   * @return encoded {@link String} corresponding to the request XML object
   * @throws SSOException if an error occurs while encoding SAML2 request
   */
  protected static String encodeRequestMessage(RequestAbstractType requestMessage, String binding)
      throws SSOException {
    Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(requestMessage);
    Element authDOM;
    try {
      //  Marshall this element, and its children, and root them in a newly created Document
      authDOM = marshaller.marshall(requestMessage);
    } catch (MarshallingException e) {
      throw new SSOException(
          "Error occurred while encoding SAML2 request, failed to marshall the SAML 2.0. "
              + "Request element XMLObject to its corresponding W3C DOM element",
          e);
    }

    StringWriter writer = new StringWriter();
    //  Writes the node out to the writer using the DOM
    XMLHelper.writeNode(authDOM, writer);

    if (SAMLConstants.SAML2_REDIRECT_BINDING_URI.equals(binding)) {
      //  Compress the message, Base 64 encode and URL encode
      Deflater deflater = new Deflater(Deflater.DEFLATED, true);
      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      try (DeflaterOutputStream deflaterOutputStream =
          new DeflaterOutputStream(byteArrayOutputStream, deflater)) {
        deflaterOutputStream.write(writer.toString().getBytes(Charset.forName("UTF-8")));
      } catch (IOException e) {
        throw new SSOException("Error occurred while deflate encoding SAML2 request", e);
      }

      String encodedRequestMessage =
          Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);
      try {
        return URLEncoder.encode(encodedRequestMessage, "UTF-8").trim();
      } catch (UnsupportedEncodingException e) {
        throw new SSOException("Error occurred while encoding SAML2 request", e);
      }
    } else if (SAMLConstants.SAML2_POST_BINDING_URI.equals(binding)) {
      return Base64.encodeBytes(
          writer.toString().getBytes(Charset.forName("UTF-8")), Base64.DONT_BREAK_LINES);
    } else {
      logger.log(
          Level.FINE,
          "Unsupported SAML2 HTTP Binding. Defaulting to " + SAMLConstants.SAML2_POST_BINDING_URI);
      return Base64.encodeBytes(
          writer.toString().getBytes(Charset.forName("UTF-8")), Base64.DONT_BREAK_LINES);
    }
  }
  private String encodeRequestMessage(RequestAbstractType requestMessage) throws SAMLSSOException {

    Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(requestMessage);
    Element authDOM = null;
    try {
      authDOM = marshaller.marshall(requestMessage);

      /* Compress the message */
      Deflater deflater = new Deflater(Deflater.DEFLATED, true);
      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      DeflaterOutputStream deflaterOutputStream =
          new DeflaterOutputStream(byteArrayOutputStream, deflater);
      StringWriter rspWrt = new StringWriter();
      XMLHelper.writeNode(authDOM, rspWrt);
      deflaterOutputStream.write(rspWrt.toString().getBytes());
      deflaterOutputStream.close();

      /* Encoding the compressed message */
      String encodedRequestMessage =
          Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);

      byteArrayOutputStream.write(byteArrayOutputStream.toByteArray());
      byteArrayOutputStream.toString();

      // log saml
      if (log.isDebugEnabled()) {
        log.debug("SAML Request  :  " + rspWrt.toString());
      }

      return URLEncoder.encode(encodedRequestMessage, "UTF-8").trim();

    } catch (MarshallingException e) {
      throw new SAMLSSOException("Error occurred while encoding SAML request", e);
    } catch (UnsupportedEncodingException e) {
      throw new SAMLSSOException("Error occurred while encoding SAML request", e);
    } catch (IOException e) {
      throw new SAMLSSOException("Error occurred while encoding SAML request", e);
    }
  }
Beispiel #12
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);
  }
  private AttributeStatement buildAttributeStatement(Map<String, String> claims) {
    AttributeStatement attStmt = null;
    if (claims != null) {
      attStmt = new AttributeStatementBuilder().buildObject();
      Iterator<String> ite = claims.keySet().iterator();

      for (int i = 0; i < claims.size(); i++) {
        Attribute attrib = new AttributeBuilder().buildObject();
        String claimUri = ite.next();
        attrib.setName(claimUri);
        // look
        // https://wiki.shibboleth.net/confluence/display/OpenSAML/OSTwoUsrManJavaAnyTypes
        XSStringBuilder stringBuilder =
            (XSStringBuilder) Configuration.getBuilderFactory().getBuilder(XSString.TYPE_NAME);
        XSString stringValue =
            stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
        stringValue.setValue(claims.get(claimUri));
        attrib.getAttributeValues().add(stringValue);
        attStmt.getAttributes().add(attrib);
      }
    }
    return attStmt;
  }
  protected String encodeRequestMessage(RequestAbstractType requestMessage, String binding)
      throws SSOAgentException {

    Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(requestMessage);
    Element authDOM = null;
    try {
      authDOM = marshaller.marshall(requestMessage);
      StringWriter rspWrt = new StringWriter();
      XMLHelper.writeNode(authDOM, rspWrt);
      if (SAMLConstants.SAML2_REDIRECT_BINDING_URI.equals(binding)) {
        // Compress the message, Base 64 encode and URL encode
        Deflater deflater = new Deflater(Deflater.DEFLATED, true);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DeflaterOutputStream deflaterOutputStream =
            new DeflaterOutputStream(byteArrayOutputStream, deflater);
        deflaterOutputStream.write(rspWrt.toString().getBytes(Charset.forName("UTF-8")));
        deflaterOutputStream.close();
        String encodedRequestMessage =
            Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);
        return URLEncoder.encode(encodedRequestMessage, "UTF-8").trim();
      } else if (SAMLConstants.SAML2_POST_BINDING_URI.equals(binding)) {
        return Base64.encodeBytes(rspWrt.toString().getBytes(), Base64.DONT_BREAK_LINES);
      } else {
        LOGGER.log(
            Level.FINE,
            "Unsupported SAML2 HTTP Binding. Defaulting to "
                + SAMLConstants.SAML2_POST_BINDING_URI);
        return Base64.encodeBytes(rspWrt.toString().getBytes(), Base64.DONT_BREAK_LINES);
      }
    } catch (MarshallingException e) {
      throw new SSOAgentException("Error occurred while encoding SAML2 request", e);
    } catch (UnsupportedEncodingException e) {
      throw new SSOAgentException("Error occurred while encoding SAML2 request", e);
    } catch (IOException e) {
      throw new SSOAgentException("Error occurred while encoding SAML2 request", e);
    }
  }
Beispiel #15
0
  @Override
  protected void internalInit() {

    CommonHelper.assertTrue(
        CommonHelper.isNotBlank(this.idpMetadata) || CommonHelper.isNotBlank(this.idpMetadataPath),
        "Either idpMetadata or idpMetadataPath must be provided");
    CommonHelper.assertNotBlank("callbackUrl", this.callbackUrl);
    if (!this.callbackUrl.startsWith("http")) {
      throw new TechnicalException("SAML callbackUrl must be absolute");
    }

    if (CommonHelper.isNotBlank(this.keystorePath)
        || CommonHelper.isNotBlank(this.keystorePassword)
        || CommonHelper.isNotBlank(this.privateKeyPassword)) {
      CommonHelper.assertNotBlank("keystorePath", this.keystorePath);
      CommonHelper.assertNotBlank("keystorePassword", this.keystorePassword);
      CommonHelper.assertNotBlank("privateKeyPassword", this.privateKeyPassword);

      // load private key from the keystore and provide it as OpenSAML credentials
      this.credentialProvider =
          new CredentialProvider(this.keystorePath, this.keystorePassword, this.privateKeyPassword);
      this.decrypter = new EncryptionProvider(this.credentialProvider).buildDecrypter();
    }

    // Bootsrap OpenSAML
    try {
      DefaultBootstrap.bootstrap();
      NamedKeyInfoGeneratorManager manager =
          Configuration.getGlobalSecurityConfiguration().getKeyInfoGeneratorManager();
      X509KeyInfoGeneratorFactory generator = new X509KeyInfoGeneratorFactory();
      generator.setEmitEntityCertificate(true);
      generator.setEmitEntityCertificateChain(true);
      manager.registerFactory(Saml2Client.SAML_METADATA_KEY_INFO_GENERATOR, generator);
    } catch (ConfigurationException e) {
      throw new SamlException("Error bootstrapping OpenSAML", e);
    }

    // required parserPool for XML processing
    final StaticBasicParserPool parserPool = newStaticBasicParserPool();
    final AbstractMetadataProvider idpMetadataProvider = idpMetadataProvider(parserPool);

    final XMLObject md;
    try {
      md = idpMetadataProvider.getMetadata();
    } catch (MetadataProviderException e) {
      throw new SamlException("Error initializing idpMetadataProvider", e);
    }

    // If no idpEntityId declared, select first EntityDescriptor entityId as our IDP entityId
    if (this.idpEntityId == null) {
      this.idpEntityId = getIdpEntityId(md);
    }

    // Generate our Service Provider metadata
    Saml2MetadataGenerator metadataGenerator = new Saml2MetadataGenerator();
    if (this.credentialProvider != null) {
      metadataGenerator.setCredentialProvider(this.credentialProvider);
      metadataGenerator.setAuthnRequestSigned(true);
    }
    // If the spEntityId is blank, use the callback url
    if (CommonHelper.isBlank(this.spEntityId)) {
      this.spEntityId = getCallbackUrl();
    }
    metadataGenerator.setEntityId(this.spEntityId);
    // Assertion consumer service url is the callback url
    metadataGenerator.setAssertionConsumerServiceUrl(getCallbackUrl());
    // for now same for logout url
    metadataGenerator.setSingleLogoutServiceUrl(getCallbackUrl());
    AbstractMetadataProvider spMetadataProvider = metadataGenerator.buildMetadataProvider();

    // Initialize metadata provider for our SP and get the XML as a String
    try {
      spMetadataProvider.initialize();
      this.spMetadata = metadataGenerator.printMetadata();
    } catch (MetadataProviderException e) {
      throw new TechnicalException("Error initializing spMetadataProvider", e);
    } catch (MarshallingException e) {
      logger.warn("Unable to print SP metadata", e);
    }

    // Put IDP and SP metadata together
    ChainingMetadataProvider metadataManager = new ChainingMetadataProvider();
    try {
      metadataManager.addMetadataProvider(idpMetadataProvider);
      metadataManager.addMetadataProvider(spMetadataProvider);
    } catch (MetadataProviderException e) {
      throw new TechnicalException("Error adding idp or sp metadatas to manager", e);
    }

    // Build the contextProvider
    this.contextProvider =
        new Saml2ContextProvider(metadataManager, this.idpEntityId, this.spEntityId);

    // Get an AuthnRequest builder
    this.authnRequestBuilder =
        new Saml2AuthnRequestBuilder(forceAuth, comparisonType, destinationBindingType);

    // Build the WebSSO handler for sending and receiving SAML2 messages
    MessageEncoder encoder = null;
    if (SAMLConstants.SAML2_POST_BINDING_URI.equals(destinationBindingType)) {
      // Get a velocity engine for the HTTP-POST binding (building of an HTML document)
      VelocityEngine velocityEngine = VelocityEngineFactory.getEngine();
      encoder = new HTTPPostEncoder(velocityEngine, "/templates/saml2-post-binding.vm");
    } else if (SAMLConstants.SAML2_REDIRECT_BINDING_URI.equals(destinationBindingType)) {
      encoder = new HTTPRedirectDeflateEncoder();
    } else {
      throw new UnsupportedOperationException(
          "Binding type - " + destinationBindingType + " is not supported");
    }

    // Do we need binding specific decoder?
    MessageDecoder decoder = new Pac4jHTTPPostDecoder(parserPool);
    this.handler =
        new Saml2WebSSOProfileHandler(
            this.credentialProvider, encoder, decoder, parserPool, destinationBindingType);

    // Build provider for digital signature validation and encryption
    this.signatureTrustEngineProvider = new SignatureTrustEngineProvider(metadataManager);

    // Build the SAML response validator
    this.responseValidator = new Saml2ResponseValidator();
    if (this.maximumAuthenticationLifetime != null) {
      this.responseValidator.setMaximumAuthenticationLifetime(this.maximumAuthenticationLifetime);
    }
  }
  /**
   * @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;
  }
 /** Constructor. */
 public SAML1ScopedStringAttributeEncoder() {
   super();
   attributeBuilder =
       (SAMLObjectBuilder<Attribute>)
           Configuration.getBuilderFactory().getBuilder(Attribute.DEFAULT_ELEMENT_NAME);
 }
 /** Constructor. */
 public SAML1NameIdentifierAttributeDefinition() {
   super();
   nameIdBuilder =
       (SAMLObjectBuilder<NameIdentifier>)
           Configuration.getBuilderFactory().getBuilder(NameIdentifier.DEFAULT_ELEMENT_NAME);
 }