private Response buildMockResponse() throws Exception { Response samlMessage = new ResponseBuilder().buildObject(); samlMessage.setID("foo"); samlMessage.setVersion(SAMLVersion.VERSION_20); samlMessage.setIssueInstant(new DateTime(0)); Issuer issuer = new IssuerBuilder().buildObject(); issuer.setValue("MockedIssuer"); samlMessage.setIssuer(issuer); Status status = new StatusBuilder().buildObject(); StatusCode statusCode = new StatusCodeBuilder().buildObject(); statusCode.setValue(StatusCode.SUCCESS_URI); status.setStatusCode(statusCode); samlMessage.setStatus(status); Assertion assertion = new AssertionBuilder().buildObject(); Subject subject = new SubjectBuilder().buildObject(); NameID nameID = new NameIDBuilder().buildObject(); nameID.setValue("SOME-UNIQUE-ID"); nameID.setFormat(NameIDType.PERSISTENT); subject.setNameID(nameID); assertion.setSubject(subject); AuthnStatement authnStatement = new AuthnStatementBuilder().buildObject(); authnStatement.setSessionIndex("Some Session String"); assertion.getAuthnStatements().add(authnStatement); AttributeStatement attributeStatement = new AttributeStatementBuilder().buildObject(); assertion.getAttributeStatements().add(attributeStatement); samlMessage.getAssertions().add(assertion); return samlMessage; }
/** * Validate the signature of a SAML2 Response and Assertion * * @param response SAML2 Response * @return true, if signature is valid. */ private void validateSignature(Response response, Assertion assertion) throws SAMLSSOException { if (SSOUtils.isAuthnResponseSigned(properties)) { if (identityProvider.getCertificate() == null || identityProvider.getCertificate().isEmpty()) { throw new SAMLSSOException( "SAMLResponse signing is enabled, but IdP doesn't have a certificate"); } if (response.getSignature() == null) { throw new SAMLSSOException( "SAMLResponse signing is enabled, but signature element " + "not found in SAML Response element."); } else { try { X509Credential credential = new X509CredentialImpl(tenantDomain, identityProvider.getCertificate()); SignatureValidator validator = new SignatureValidator(credential); validator.validate(response.getSignature()); } catch (ValidationException e) { throw new SAMLSSOException("Signature validation failed for SAML Response", e); } } } if (SSOUtils.isAssertionSigningEnabled(properties)) { if (identityProvider.getCertificate() == null || identityProvider.getCertificate().isEmpty()) { throw new SAMLSSOException( "SAMLAssertion signing is enabled, but IdP doesn't have a certificate"); } if (assertion.getSignature() == null) { throw new SAMLSSOException( "SAMLAssertion signing is enabled, but signature element " + "not found in SAML Assertion element."); } else { try { X509Credential credential = new X509CredentialImpl(tenantDomain, identityProvider.getCertificate()); SignatureValidator validator = new SignatureValidator(credential); validator.validate(assertion.getSignature()); } catch (ValidationException e) { throw new SAMLSSOException("Signature validation failed for SAML Assertion", e); } } } }
/** * Validate the signature of a SAML2 Response and Assertion * * @param response SAML2 Response * @return true, if signature is valid. */ protected void validateSignature(Response response, Assertion assertion) throws SSOAgentException { if (SSOAgentDataHolder.getInstance().getSignatureValidator() != null) { // Custom implemetation of signature validation SAMLSignatureValidator signatureValidatorUtility = (SAMLSignatureValidator) SSOAgentDataHolder.getInstance().getSignatureValidator(); signatureValidatorUtility.validateSignature(response, assertion, ssoAgentConfig); } else { // If custom implementation not found, Execute the default implementation if (ssoAgentConfig.getSAML2().isResponseSigned()) { if (response.getSignature() == null) { throw new SSOAgentException( "SAML2 Response signing is enabled, but signature element not found in SAML2 Response element"); } else { try { SignatureValidator validator = new SignatureValidator( new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential())); validator.validate(response.getSignature()); } catch (ValidationException e) { if (log.isDebugEnabled()) { log.debug("Validation exception : ", e); } throw new SSOAgentException("Signature validation failed for SAML2 Response"); } } } if (ssoAgentConfig.getSAML2().isAssertionSigned()) { if (assertion.getSignature() == null) { throw new SSOAgentException( "SAML2 Assertion signing is enabled, but signature element not found in SAML2 Assertion element"); } else { try { SignatureValidator validator = new SignatureValidator( new X509CredentialImpl(ssoAgentConfig.getSAML2().getSSOAgentX509Credential())); validator.validate(assertion.getSignature()); } catch (ValidationException e) { if (log.isDebugEnabled()) { log.debug("Validation exception : ", e); } throw new SSOAgentException("Signature validation failed for SAML2 Assertion"); } } } } }
/** * Validate the AudienceRestriction of SAML2 Response * * @param assertion SAML2 Assertion * @return validity */ private void validateAudienceRestriction(Assertion assertion) throws SAMLSSOException { if (assertion != null) { Conditions conditions = assertion.getConditions(); if (conditions != null) { List<AudienceRestriction> audienceRestrictions = conditions.getAudienceRestrictions(); if (audienceRestrictions != null && !audienceRestrictions.isEmpty()) { for (AudienceRestriction audienceRestriction : audienceRestrictions) { if (CollectionUtils.isNotEmpty(audienceRestriction.getAudiences())) { boolean audienceFound = false; for (Audience audience : audienceRestriction.getAudiences()) { if (properties .get(IdentityApplicationConstants.Authenticator.SAML2SSO.SP_ENTITY_ID) .equals(audience.getAudienceURI())) { audienceFound = true; break; } } if (!audienceFound) { throw new SAMLSSOException("SAML Assertion Audience Restriction validation failed"); } } else { throw new SAMLSSOException( "SAML Response's AudienceRestriction doesn't contain Audiences"); } } } else { throw new SAMLSSOException("SAML Response doesn't contain AudienceRestrictions"); } } else { throw new SAMLSSOException("SAML Response doesn't contain Conditions"); } } }
/** * Validate the AudienceRestriction of SAML2 Response * * @param assertion SAML2 Assertion * @return validity */ protected void validateAudienceRestriction(Assertion assertion) throws SSOAgentException { if (assertion != null) { Conditions conditions = assertion.getConditions(); if (conditions != null) { List<AudienceRestriction> audienceRestrictions = conditions.getAudienceRestrictions(); if (audienceRestrictions != null && !audienceRestrictions.isEmpty()) { boolean audienceFound = false; for (AudienceRestriction audienceRestriction : audienceRestrictions) { if (audienceRestriction.getAudiences() != null && !audienceRestriction.getAudiences().isEmpty()) { for (Audience audience : audienceRestriction.getAudiences()) { if (ssoAgentConfig.getSAML2().getSPEntityId().equals(audience.getAudienceURI())) { audienceFound = true; break; } } } if (audienceFound) { break; } } if (!audienceFound) { throw new SSOAgentException("SAML2 Assertion Audience Restriction validation failed"); } } else { throw new SSOAgentException("SAML2 Response doesn't contain AudienceRestrictions"); } } else { throw new SSOAgentException("SAML2 Response doesn't contain Conditions"); } } }
/* * Process the response and returns the results */ private Map<String, String> getAssertionStatements(Assertion assertion) { Map<String, String> results = new HashMap<String, String>(); if (assertion != null && assertion.getAttributeStatements() != null) { List<AttributeStatement> attributeStatementList = assertion.getAttributeStatements(); for (AttributeStatement statement : attributeStatementList) { List<Attribute> attributesList = statement.getAttributes(); for (Attribute attribute : attributesList) { Element value = attribute.getAttributeValues().get(0).getDOM(); String attributeValue = value.getTextContent(); results.put(attribute.getName(), attributeValue); } } } return results; }
/** * Returns SAML 2.0 Assertion Attribute Statement content. * * @param assertion the SAML 2.0 Assertion whose content is to be returned * @return Attribute Statement content of the SAML 2.0 Assertion specified */ protected static Map<String, String> getAssertionStatements(Assertion assertion) { Map<String, String> results = new HashMap<>(); if ((Optional.ofNullable(assertion).isPresent()) && (Optional.ofNullable(assertion.getAttributeStatements()).isPresent())) { Stream<AttributeStatement> attributeStatements = assertion.getAttributeStatements().stream(); attributeStatements.forEach( attributeStatement -> attributeStatement .getAttributes() .stream() .forEach( attribute -> { Element value = attribute.getAttributeValues().get(0).getDOM(); String attributeValue = value.getTextContent(); results.put(attribute.getName(), attributeValue); })); } return results; }
private Map<String, Object> getUserAttributes(ResponseImpl samlResponse) { Map<String, Object> userAttributes = new HashMap<>(); // Add 'Subject' Assertion assertion = samlResponse.getAssertions().get(0); userAttributes.put( SAMLConstants.SAML2_ASSERTION_SUBJECT, assertion.getSubject().getNameID().getValue()); // Add other user attributes. List<AttributeStatement> attributeStatements = assertion.getAttributeStatements(); if (attributeStatements != null) { for (AttributeStatement attributeStatement : attributeStatements) { List<Attribute> attributes = attributeStatement.getAttributes(); for (Attribute attribute : attributes) { userAttributes.put( attribute.getName(), attribute.getAttributeValues().get(0).getDOM().getTextContent()); } } } return userAttributes; }
private Saml2Credentials buildSaml2Credentials(final ExtendedSAMLMessageContext context) { NameID nameId = (NameID) context.getSubjectNameIdentifier(); Assertion subjectAssertion = context.getSubjectAssertion(); List<Attribute> attributes = new ArrayList<Attribute>(); for (AttributeStatement attributeStatement : subjectAssertion.getAttributeStatements()) { for (Attribute attribute : attributeStatement.getAttributes()) { attributes.add(attribute); } if (attributeStatement.getEncryptedAttributes().size() > 0) { logger.warn("Encrypted attributes returned, but no keystore was provided."); } for (EncryptedAttribute encryptedAttribute : attributeStatement.getEncryptedAttributes()) { try { attributes.add(decrypter.decrypt(encryptedAttribute)); } catch (DecryptionException e) { logger.warn("Decryption of attribute failed, continue with the next one", e); } } } return new Saml2Credentials(nameId, attributes, subjectAssertion.getConditions(), getName()); }
private void processSSOResponse(HttpServletRequest request) throws SAMLSSOException { Response samlResponse = (Response) unmarshall( new String( Base64.decode(request.getParameter(SSOConstants.HTTP_POST_PARAM_SAML2_RESP)))); Assertion assertion = null; if (SSOUtils.isAssertionEncryptionEnabled(properties)) { List<EncryptedAssertion> encryptedAssertions = samlResponse.getEncryptedAssertions(); EncryptedAssertion encryptedAssertion = null; if (CollectionUtils.isNotEmpty(encryptedAssertions)) { encryptedAssertion = encryptedAssertions.get(0); try { assertion = getDecryptedAssertion(encryptedAssertion); } catch (Exception e) { throw new SAMLSSOException("Unable to decrypt the SAML Assertion", e); } } } else { List<Assertion> assertions = samlResponse.getAssertions(); if (CollectionUtils.isNotEmpty(assertions)) { assertion = assertions.get(0); } } if (assertion == null) { if (samlResponse.getStatus() != null && samlResponse.getStatus().getStatusCode() != null && samlResponse .getStatus() .getStatusCode() .getValue() .equals(SSOConstants.StatusCodes.IDENTITY_PROVIDER_ERROR) && samlResponse.getStatus().getStatusCode().getStatusCode() != null && samlResponse .getStatus() .getStatusCode() .getStatusCode() .getValue() .equals(SSOConstants.StatusCodes.NO_PASSIVE)) { return; } throw new SAMLSSOException("SAML Assertion not found in the Response"); } // Get the subject name from the Response Object and forward it to login_action.jsp String subject = null; String nameQualifier = null; String spNameQualifier = null; if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) { subject = assertion.getSubject().getNameID().getValue(); } if (subject == null) { throw new SAMLSSOException("SAML Response does not contain the name of the subject"); } request.getSession().setAttribute("username", subject); // get the subject nameQualifier = assertion.getSubject().getNameID().getNameQualifier(); spNameQualifier = assertion.getSubject().getNameID().getSPNameQualifier(); // validate audience restriction validateAudienceRestriction(assertion); // validate signature this SP only looking for assertion signature validateSignature(samlResponse, assertion); request.getSession(false).setAttribute("samlssoAttributes", getAssertionStatements(assertion)); // For removing the session when the single sign out request made by the SP itself if (SSOUtils.isLogoutEnabled(properties)) { String sessionId = assertion.getAuthnStatements().get(0).getSessionIndex(); if (sessionId == null) { throw new SAMLSSOException( "Single Logout is enabled but IdP Session ID not found in SAML Assertion"); } request.getSession().setAttribute(SSOConstants.IDP_SESSION, sessionId); request.getSession().setAttribute(SSOConstants.LOGOUT_USERNAME, nameQualifier); request.getSession().setAttribute(SSOConstants.SP_NAME_QUALIFIER, spNameQualifier); } }
protected void processSSOResponse(HttpServletRequest request) throws SSOAgentException { LoggedInSessionBean sessionBean = new LoggedInSessionBean(); sessionBean.setSAML2SSO(sessionBean.new SAML2SSO()); String saml2ResponseString = new String( Base64.decode( request.getParameter(SSOAgentConstants.SAML2SSO.HTTP_POST_PARAM_SAML2_RESP)), Charset.forName("UTF-8")); Response saml2Response = (Response) SSOAgentUtils.unmarshall(saml2ResponseString); sessionBean.getSAML2SSO().setResponseString(saml2ResponseString); sessionBean.getSAML2SSO().setSAMLResponse(saml2Response); Assertion assertion = null; if (ssoAgentConfig.getSAML2().isAssertionEncrypted()) { List<EncryptedAssertion> encryptedAssertions = saml2Response.getEncryptedAssertions(); EncryptedAssertion encryptedAssertion = null; if (!org.apache.commons.collections.CollectionUtils.isEmpty(encryptedAssertions)) { encryptedAssertion = encryptedAssertions.get(0); try { assertion = getDecryptedAssertion(encryptedAssertion); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug("Assertion decryption failure : ", e); } throw new SSOAgentException("Unable to decrypt the SAML2 Assertion"); } } } else { List<Assertion> assertions = saml2Response.getAssertions(); if (assertions != null && !assertions.isEmpty()) { assertion = assertions.get(0); } } if (assertion == null) { if (isNoPassive(saml2Response)) { LOGGER.log(Level.FINE, "Cannot authenticate in passive mode"); return; } throw new SSOAgentException("SAML2 Assertion not found in the Response"); } String idPEntityIdValue = assertion.getIssuer().getValue(); if (idPEntityIdValue == null || idPEntityIdValue.isEmpty()) { throw new SSOAgentException("SAML2 Response does not contain an Issuer value"); } else if (!idPEntityIdValue.equals(ssoAgentConfig.getSAML2().getIdPEntityId())) { throw new SSOAgentException("SAML2 Response Issuer verification failed"); } sessionBean.getSAML2SSO().setAssertion(assertion); // Cannot marshall SAML assertion here, before signature validation due to a weird issue in // OpenSAML // Get the subject name from the Response Object and forward it to login_action.jsp String subject = null; if (assertion.getSubject() != null && assertion.getSubject().getNameID() != null) { subject = assertion.getSubject().getNameID().getValue(); } if (subject == null) { throw new SSOAgentException("SAML2 Response does not contain the name of the subject"); } sessionBean.getSAML2SSO().setSubjectId(subject); // set the subject request.getSession().setAttribute(SSOAgentConstants.SESSION_BEAN_NAME, sessionBean); // validate audience restriction validateAudienceRestriction(assertion); // validate signature validateSignature(saml2Response, assertion); // Marshalling SAML2 assertion after signature validation due to a weird issue in OpenSAML sessionBean.getSAML2SSO().setAssertionString(marshall(assertion)); ((LoggedInSessionBean) request.getSession().getAttribute(SSOAgentConstants.SESSION_BEAN_NAME)) .getSAML2SSO() .setSubjectAttributes(getAssertionStatements(assertion)); // For removing the session when the single sign out request made by the SP itself if (ssoAgentConfig.getSAML2().isSLOEnabled()) { String sessionId = assertion.getAuthnStatements().get(0).getSessionIndex(); if (sessionId == null) { throw new SSOAgentException( "Single Logout is enabled but IdP Session ID not found in SAML2 Assertion"); } ((LoggedInSessionBean) request.getSession().getAttribute(SSOAgentConstants.SESSION_BEAN_NAME)) .getSAML2SSO() .setSessionIndex(sessionId); SSOAgentSessionManager.addAuthenticatedSession(request.getSession(false)); } request.getSession().setAttribute(SSOAgentConstants.SESSION_BEAN_NAME, sessionBean); }
private Assertion buildSAMLAssertion( SAMLSSOAuthnReqDTO authReqDTO, DateTime notOnOrAfter, String sessionId) throws IdentityException { try { DateTime currentTime = new DateTime(); Assertion samlAssertion = new AssertionBuilder().buildObject(); samlAssertion.setID(SAMLSSOUtil.createID()); samlAssertion.setVersion(SAMLVersion.VERSION_20); samlAssertion.setIssuer(SAMLSSOUtil.getIssuer()); samlAssertion.setIssueInstant(currentTime); Subject subject = new SubjectBuilder().buildObject(); NameID nameId = new NameIDBuilder().buildObject(); if (authReqDTO.getUseFullyQualifiedUsernameAsSubject()) { nameId.setValue(authReqDTO.getUsername()); nameId.setFormat(NameIdentifier.EMAIL); } else { nameId.setValue(MultitenantUtils.getTenantAwareUsername(authReqDTO.getUsername())); nameId.setFormat(authReqDTO.getNameIDFormat()); } subject.setNameID(nameId); SubjectConfirmation subjectConfirmation = new SubjectConfirmationBuilder().buildObject(); subjectConfirmation.setMethod(SAMLSSOConstants.SUBJECT_CONFIRM_BEARER); SubjectConfirmationData scData = new SubjectConfirmationDataBuilder().buildObject(); scData.setRecipient(authReqDTO.getAssertionConsumerURL()); scData.setNotOnOrAfter(notOnOrAfter); scData.setInResponseTo(authReqDTO.getId()); subjectConfirmation.setSubjectConfirmationData(scData); subject.getSubjectConfirmations().add(subjectConfirmation); samlAssertion.setSubject(subject); AuthnStatement authStmt = new AuthnStatementBuilder().buildObject(); authStmt.setAuthnInstant(new DateTime()); AuthnContext authContext = new AuthnContextBuilder().buildObject(); AuthnContextClassRef authCtxClassRef = new AuthnContextClassRefBuilder().buildObject(); authCtxClassRef.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX); authContext.setAuthnContextClassRef(authCtxClassRef); authStmt.setAuthnContext(authContext); if (authReqDTO.isDoSingleLogout()) { authStmt.setSessionIndex(sessionId); } samlAssertion.getAuthnStatements().add(authStmt); /* * If <AttributeConsumingServiceIndex> element is in the * <AuthnRequest> and * according to the spec 2.0 the subject MUST be in the assertion */ Map<String, String> claims = SAMLSSOUtil.getAttributes(authReqDTO); if (claims != null) { samlAssertion.getAttributeStatements().add(buildAttributeStatement(claims)); } AudienceRestriction audienceRestriction = new AudienceRestrictionBuilder().buildObject(); Audience issuerAudience = new AudienceBuilder().buildObject(); issuerAudience.setAudienceURI(authReqDTO.getIssuer()); audienceRestriction.getAudiences().add(issuerAudience); if (authReqDTO.getRequestedAudiences() != null) { for (String requestedAudience : authReqDTO.getRequestedAudiences()) { Audience audience = new AudienceBuilder().buildObject(); audience.setAudienceURI(requestedAudience); audienceRestriction.getAudiences().add(audience); } } Conditions conditions = new ConditionsBuilder().buildObject(); conditions.setNotBefore(currentTime); conditions.setNotOnOrAfter(notOnOrAfter); conditions.getAudienceRestrictions().add(audienceRestriction); samlAssertion.setConditions(conditions); if (authReqDTO.getDoSignAssertions()) { SAMLSSOUtil.setSignature( samlAssertion, XMLSignature.ALGO_ID_SIGNATURE_RSA, new SignKeyDataHolder(authReqDTO.getUsername())); } return samlAssertion; } catch (Exception e) { log.error("Error when reading claim values for generating SAML Response", e); throw new IdentityException( "Error when reading claim values for generating SAML Response", e); } }
/* * Unit test for serialization/deserialization check on * AuthenticationResponse and validation of Assertion's signature * afterwards. */ @Test public void testAssertion() throws Exception { // Setup KeyPair keyPair = generateKeyPair(); DateTime notBefore = new DateTime(); DateTime notAfter = notBefore.plusMonths(1); X509Certificate certificate = generateSelfSignedCertificate(keyPair, "CN=Test", notBefore, notAfter); KeyStore.PrivateKeyEntry privateKeyEntry = new KeyStore.PrivateKeyEntry(keyPair.getPrivate(), new Certificate[] {certificate}); String userId = UUID.randomUUID().toString(); String attributeName = "urn:test:attribute"; Attribute attribute = new Attribute(attributeName, AttributeType.STRING, UUID.randomUUID().toString()); Map<String, Attribute> attributes = new HashMap<String, Attribute>(); attributes.put(attributeName, attribute); String issuerName = "test-issuer"; String requestIssuer = "request-issuer"; String requestId = UUID.randomUUID().toString(); String recipient = "http://www.testsp.com/saml"; Assertion assertion = Saml2Util.getAssertion( issuerName, requestId, requestIssuer, recipient, 5, new DateTime(), SamlAuthenticationPolicy.IDENTIFICATION, userId, attributes, null, null); // Operate: sign assertion Saml2Util.sign(assertion, privateKeyEntry); // Verify List<X509Certificate> certChain = Saml2Util.validateSignature(assertion.getSignature()); assertNotNull(certChain); assertEquals(1, certChain.size()); // Operate: validate assertion AuthenticationResponse authenticationResponse = Saml2Util.validateAssertion( assertion, new DateTime(), 5, requestIssuer, recipient, requestId, null, null); // Verify assertNotNull(authenticationResponse); assertNotNull(authenticationResponse.getAssertion()); // Operate: serialize AuthenticationResponse ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(authenticationResponse); oos.close(); // Operate: deserialize AuthenticationResponse byte[] input = out.toByteArray(); InputStream in = new ByteArrayInputStream(input); ObjectInputStream ois = new ObjectInputStream(in); Object o = ois.readObject(); AuthenticationResponse copy = (AuthenticationResponse) o; // Verify assertNotNull(copy); Assertion assertionCopy = copy.getAssertion(); assertNotNull(assertionCopy); Saml2Util.validateSignature(assertionCopy.getSignature()); AuthenticationResponse authenticationResponseCopy = Saml2Util.validateAssertion( assertionCopy, new DateTime(), 5, requestIssuer, recipient, requestId, null, null); assertEquals( authenticationResponse.getEncodedAssertion(), authenticationResponseCopy.getEncodedAssertion()); }
private static List<AttributeStatement> validateAssertion( Assertion samlAssertion, SignatureTrustEngine sigTrustEngine, String myURI, MessageReplayRule replayRule, VerifySignatureType verifySignature, boolean responseSignatureVerified) throws SAMLValidationException { if (logger.isDebugEnabled()) { logger.debug( "validateAndExtractContext(Assertion, String, SignatureTrustEngine, String, MessageReplayRule, VerifySignatureType) - start"); //$NON-NLS-1$ } // Check the replay attack if (replayRule != null) { BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext(); // messageContext.setInboundMessage(samlResponse); if (samlAssertion.getIssuer() != null) messageContext.setInboundMessageIssuer(samlAssertion.getIssuer().getValue()); messageContext.setInboundSAMLMessageId(samlAssertion.getID()); try { replayRule.evaluate(messageContext); } catch (SecurityPolicyException e) { logger.error( "validateAndExtractContext(Assertion, String, SignatureTrustEngine, String, MessageReplayRule, VerifySignatureType)", e); //$NON-NLS-1$ throw createSAMLValidationException("Possible Replay Attack for Assertion", false, e); } } if (verifySignature != VerifySignatureType.never) { Signature signature = samlAssertion.getSignature(); if (signature == null) { if (verifySignature == VerifySignatureType.force && !responseSignatureVerified) { throw createSAMLValidationException("Signature does exist in Assertion", true); } } else { verifySignature(signature, samlAssertion.getIssuer().getValue(), sigTrustEngine); } } DateTime dt = new DateTime(); // get subject (code below only processes first Subject confirmation) Subject subject = samlAssertion.getSubject(); SubjectSchemaValidator subjectSchemaValidator = new SubjectSchemaValidator(); try { subjectSchemaValidator.validate(subject); } catch (ValidationException e) { logger.error( "validateAndExtractContext(Assertion, String, SignatureTrustEngine, String, MessageReplayRule, VerifySignatureType)", e); //$NON-NLS-1$ throw createSAMLValidationException("Subject validation failed: " + e.getMessage(), true, e); } List<SubjectConfirmation> subjectConfirmations = subject.getSubjectConfirmations(); for (SubjectConfirmation subjectConfirmation : subjectConfirmations) { SubjectConfirmationSchemaValidator subjectConfirmationSchemaValidator = new SubjectConfirmationSchemaValidator(); try { subjectConfirmationSchemaValidator.validate(subjectConfirmation); } catch (ValidationException e) { logger.error( "validateAndExtractContext(Assertion, String, SignatureTrustEngine, String, MessageReplayRule, VerifySignatureType)", e); //$NON-NLS-1$ throw createSAMLValidationException( "Subject Confirmation validation failed: " + e.getMessage(), true, e); } SubjectConfirmationData subjectConfirmationData = subjectConfirmation.getSubjectConfirmationData(); try { subjectConfirmationSchemaValidator.validate(subjectConfirmation); } catch (ValidationException e) { logger.error( "validateAndExtractContext(Assertion, String, SignatureTrustEngine, String, MessageReplayRule, VerifySignatureType)", e); //$NON-NLS-1$ throw createSAMLValidationException( "Subject Confirmation validation failed: " + e.getMessage(), true, e); } // verify the validity of time using clock skew, subjectConfirmationData.getNotBefore() and // subjectConfirmationData.getNotOnOrAfter()@ DateTime notBefore = subjectConfirmationData.getNotBefore(); DateTime notAfter = subjectConfirmationData.getNotOnOrAfter(); if (notBefore != null && dt.isBefore(notBefore)) { throw createSAMLValidationException("Subject confirmation expired.", true); } if (notAfter != null && (dt.equals(notAfter) || dt.isAfter(notAfter))) { throw createSAMLValidationException("Subject confirmation expired.", true); } } // validate conditions Conditions conditions = samlAssertion.getConditions(); // Validate the spec ConditionsSpecValidator conditionValidator = new ConditionsSpecValidator(); try { conditionValidator.validate(conditions); } catch (ValidationException e) { logger.error( "validateAndExtractContext(Assertion, String, SignatureTrustEngine, String, MessageReplayRule, VerifySignatureType)", e); //$NON-NLS-1$ throw createSAMLValidationException("Condition Validity Failed.", true, e); } // verify the validity of time using clock skew, conditions.getNotBefore() and // conditions.getNotOnOrAfter()@ DateTime notBefore = conditions.getNotBefore(); DateTime notAfter = conditions.getNotOnOrAfter(); if (notBefore != null && dt.isBefore(notBefore)) { throw createSAMLValidationException("Assertion expired.", true); } if (notAfter != null && (dt.equals(notAfter) || dt.isAfter(notAfter))) { throw createSAMLValidationException("Assertion expired.", true); } for (Condition condition : conditions.getConditions()) { if (condition instanceof AudienceRestriction) { if (myURI != null && myURI.length() > 0) { boolean audiencePresent = false; boolean iAmOneOfTheAudience = false; AudienceRestriction audienceRestriction = (AudienceRestriction) condition; for (Audience audience : audienceRestriction.getAudiences()) { audiencePresent = true; String audienceURI = audience.getAudienceURI(); if (myURI.equals(audienceURI)) { iAmOneOfTheAudience = true; break; } } if (!(audiencePresent && iAmOneOfTheAudience)) { throw createSAMLValidationException( "None of the audience is intended for me: " + myURI, false); } } } } List<AttributeStatement> asList = samlAssertion.getAttributeStatements(); if (logger.isDebugEnabled()) { logger.debug( "validateAndExtractContext(Assertion, String, SignatureTrustEngine, String, MessageReplayRule, VerifySignatureType) - end"); //$NON-NLS-1$ } return asList; }