/** * 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"); } } }
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); } }
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; }