public static SAMLConfiguration getInstance(boolean noInit) { if (logger.isDebugEnabled()) { logger.debug("getInstance(String, boolean) - start"); // $NON-NLS-1$ } if (instance == null) { instance = new SAMLConfiguration(); } instance.setNoInit(noInit); if (logger.isDebugEnabled()) { logger.debug("getInstance(String, boolean) - end"); // $NON-NLS-1$ } return instance; }
/** * @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; }