use of org.apache.wss4j.common.ext.WSSecurityException in project cxf by apache.
the class SAMLSSOResponseValidator method validateSubjectConfirmation.
/**
* Validate a (Bearer) Subject Confirmation
*/
private void validateSubjectConfirmation(org.opensaml.saml.saml2.core.SubjectConfirmationData subjectConfData, String id, boolean postBinding) throws WSSecurityException {
if (subjectConfData == null) {
LOG.warning("Subject Confirmation Data of a Bearer Subject Confirmation is null");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// Recipient must match assertion consumer URL
String recipient = subjectConfData.getRecipient();
if (recipient == null || !recipient.equals(assertionConsumerURL)) {
LOG.warning("Recipient " + recipient + " does not match assertion consumer URL " + assertionConsumerURL);
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// We must have a NotOnOrAfter timestamp
if (subjectConfData.getNotOnOrAfter() == null || subjectConfData.getNotOnOrAfter().isBeforeNow()) {
LOG.warning("Subject Conf Data does not contain NotOnOrAfter or it has expired");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// Need to keep bearer assertion IDs based on NotOnOrAfter to detect replay attacks
if (postBinding && replayCache != null) {
if (!replayCache.contains(id)) {
Instant expires = Instant.ofEpochMilli(subjectConfData.getNotOnOrAfter().toDate().getTime());
replayCache.putId(id, expires);
} else {
LOG.warning("Replay attack with token id: " + id);
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
}
// Check address
if (subjectConfData.getAddress() != null && clientAddress != null && !subjectConfData.getAddress().equals(clientAddress)) {
LOG.warning("Subject Conf Data address " + subjectConfData.getAddress() + " does not match" + " client address " + clientAddress);
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// It must not contain a NotBefore timestamp
if (subjectConfData.getNotBefore() != null) {
LOG.warning("The Subject Conf Data must not contain a NotBefore timestamp");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// InResponseTo must match the AuthnRequest request Id
if (requestId != null && !requestId.equals(subjectConfData.getInResponseTo())) {
LOG.warning("The InResponseTo String does match the original request id " + requestId);
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
} else if (requestId == null && subjectConfData.getInResponseTo() != null) {
LOG.warning("No InResponseTo String is allowed for the unsolicted case");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
}
use of org.apache.wss4j.common.ext.WSSecurityException in project cxf by apache.
the class SAMLSSOResponseValidator method validateSamlResponse.
/**
* Validate a SAML 2 Protocol Response
* @param samlResponse
* @param postBinding
* @return a SSOValidatorResponse object
* @throws WSSecurityException
*/
public SSOValidatorResponse validateSamlResponse(org.opensaml.saml.saml2.core.Response samlResponse, boolean postBinding) throws WSSecurityException {
// Check the Issuer
validateIssuer(samlResponse.getIssuer());
// The Response must contain at least one Assertion.
if (samlResponse.getAssertions() == null || samlResponse.getAssertions().isEmpty()) {
LOG.warning("The Response must contain at least one Assertion");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// The Response must contain a Destination that matches the assertionConsumerURL if it is
// signed
String destination = samlResponse.getDestination();
if (samlResponse.isSigned() && (destination == null || !destination.equals(assertionConsumerURL))) {
LOG.warning("The Response must contain a destination that matches the assertion consumer URL");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
if (enforceResponseSigned && !samlResponse.isSigned()) {
LOG.warning("The Response must be signed!");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// Validate Assertions
org.opensaml.saml.saml2.core.Assertion validAssertion = null;
Instant sessionNotOnOrAfter = null;
for (org.opensaml.saml.saml2.core.Assertion assertion : samlResponse.getAssertions()) {
// Check the Issuer
if (assertion.getIssuer() == null) {
LOG.warning("Assertion Issuer must not be null");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
validateIssuer(assertion.getIssuer());
if (!samlResponse.isSigned() && enforceAssertionsSigned && assertion.getSignature() == null) {
LOG.warning("The enclosed assertions in the SAML Response must be signed");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
// Check for AuthnStatements and validate the Subject accordingly
if (assertion.getAuthnStatements() != null && !assertion.getAuthnStatements().isEmpty()) {
org.opensaml.saml.saml2.core.Subject subject = assertion.getSubject();
org.opensaml.saml.saml2.core.SubjectConfirmation subjectConf = validateAuthenticationSubject(subject, assertion.getID(), postBinding);
if (subjectConf != null) {
validateAudienceRestrictionCondition(assertion.getConditions());
validAssertion = assertion;
sessionNotOnOrAfter = null;
// Store Session NotOnOrAfter
for (AuthnStatement authnStatment : assertion.getAuthnStatements()) {
if (authnStatment.getSessionNotOnOrAfter() != null) {
sessionNotOnOrAfter = Instant.ofEpochMilli(authnStatment.getSessionNotOnOrAfter().toDate().getTime());
}
}
// Fall back to the SubjectConfirmationData NotOnOrAfter if we have no session NotOnOrAfter
if (sessionNotOnOrAfter == null) {
sessionNotOnOrAfter = Instant.ofEpochMilli(subjectConf.getSubjectConfirmationData().getNotOnOrAfter().toDate().getTime());
}
}
}
}
if (validAssertion == null) {
LOG.warning("The Response did not contain any Authentication Statement that matched " + "the Subject Confirmation criteria");
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
}
SSOValidatorResponse validatorResponse = new SSOValidatorResponse();
validatorResponse.setResponseId(samlResponse.getID());
validatorResponse.setSessionNotOnOrAfter(sessionNotOnOrAfter);
if (samlResponse.getIssueInstant() != null) {
validatorResponse.setCreated(Instant.ofEpochMilli(samlResponse.getIssueInstant().toDate().getTime()));
}
Element assertionElement = validAssertion.getDOM();
Element clonedAssertionElement = (Element) assertionElement.cloneNode(true);
validatorResponse.setAssertionElement(clonedAssertionElement);
validatorResponse.setAssertion(DOM2Writer.nodeToString(clonedAssertionElement));
validatorResponse.setOpensamlAssertion(validAssertion);
return validatorResponse;
}
use of org.apache.wss4j.common.ext.WSSecurityException in project cxf by apache.
the class CrossDomainValidator method validate.
public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
Credential validatedCredential = super.validate(credential, data);
SamlAssertionWrapper token = validatedCredential.getSamlAssertion();
if (token == null || token.getSaml2() == null || !"b-issuer".equals(token.getIssuerString())) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
}
return validatedCredential;
}
use of org.apache.wss4j.common.ext.WSSecurityException in project cxf by apache.
the class CustomBSTTokenValidator method validate.
public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
Credential validatedCredential = super.validate(credential, data);
SamlAssertionWrapper transformedToken = validatedCredential.getTransformedToken();
if (transformedToken == null || transformedToken.getSaml2() == null || !"DoubleItSTSIssuer".equals(transformedToken.getIssuerString())) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
}
return validatedCredential;
}
use of org.apache.wss4j.common.ext.WSSecurityException in project cxf by apache.
the class DifferentRealmValidator method validate.
public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
Credential validatedCredential = super.validate(credential, data);
SamlAssertionWrapper transformedToken = validatedCredential.getTransformedToken();
if (transformedToken == null || transformedToken.getSaml2() == null || !"B-Issuer".equals(transformedToken.getIssuerString())) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
}
Assertion assertion = transformedToken.getSaml2();
if (!"B-Principal".equals(assertion.getSubject().getNameID().getValue())) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
}
return validatedCredential;
}
Aggregations