Repository: cxf-fediz Updated Branches: refs/heads/master 7c8b515e1 -> 70b5a85b1
Simplifying the SamlAssertionValidator + pick up latest fixes from WSS4J Project: http://git-wip-us.apache.org/repos/asf/cxf-fediz/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-fediz/commit/70b5a85b Tree: http://git-wip-us.apache.org/repos/asf/cxf-fediz/tree/70b5a85b Diff: http://git-wip-us.apache.org/repos/asf/cxf-fediz/diff/70b5a85b Branch: refs/heads/master Commit: 70b5a85b1ff8f31f08bcd3dada699e3a9af8c887 Parents: 7c8b515 Author: Colm O hEigeartaigh <[email protected]> Authored: Mon Jan 19 11:13:44 2015 +0000 Committer: Colm O hEigeartaigh <[email protected]> Committed: Mon Jan 19 11:13:44 2015 +0000 ---------------------------------------------------------------------- .../fediz/core/saml/SamlAssertionValidator.java | 168 +------------------ pom.xml | 2 +- 2 files changed, 10 insertions(+), 160 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/70b5a85b/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SamlAssertionValidator.java ---------------------------------------------------------------------- diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SamlAssertionValidator.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SamlAssertionValidator.java index f48945c..0b9df6e 100644 --- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SamlAssertionValidator.java +++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SamlAssertionValidator.java @@ -21,48 +21,22 @@ package org.apache.cxf.fediz.core.saml; import java.util.ArrayList; import java.util.Collection; -import java.util.Date; -import java.util.List; import java.util.regex.Pattern; import org.apache.cxf.fediz.core.saml.FedizSignatureTrustValidator.TRUST_TYPE; -import org.apache.wss4j.common.cache.ReplayCache; -import org.apache.wss4j.common.crypto.Crypto; import org.apache.wss4j.common.ext.WSSecurityException; -import org.apache.wss4j.common.saml.OpenSAMLUtil; import org.apache.wss4j.common.saml.SAMLKeyInfo; import org.apache.wss4j.common.saml.SamlAssertionWrapper; import org.apache.wss4j.dom.handler.RequestData; import org.apache.wss4j.dom.validate.Credential; -import org.apache.wss4j.dom.validate.Validator; -import org.joda.time.DateTime; -import org.opensaml.common.SAMLVersion; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * This class validates a SAML Assertion, which is wrapped in an "AssertionWrapper" instance. - * It assumes that the AssertionWrapper instance has already verified the signature on the - * assertion (done by the SAMLTokenProcessor). It verifies trust in the signature, and also - * checks that the Subject contains a KeyInfo (and processes it) for the holder-of-key case, - * and verifies that the Assertion is signed as well for holder-of-key. + * This class validates a SAML Assertion by wrapping the default WSS4J SamlAssertionValidator. + * It extends it by verifying trust in the Signature using a TRUST_TYPE, as well as subject DN + * constraints. */ -public class SamlAssertionValidator implements Validator { +public class SamlAssertionValidator extends org.apache.wss4j.dom.validate.SamlAssertionValidator { - private static final Logger LOG = LoggerFactory.getLogger(SamlAssertionValidator.class); - - /** - * The time in seconds in the future within which the NotBefore time of an incoming - * Assertion is valid. The default is 60 seconds. - */ - private int futureTTL = 60; - - /** - * Whether to validate the signature of the Assertion (if it exists) against the - * relevant profile. Default is true. - */ - private boolean validateSignatureAgainstProfile = true; - private TRUST_TYPE signatureTrustType = TRUST_TYPE.CHAIN_TRUST; /** @@ -70,22 +44,6 @@ public class SamlAssertionValidator implements Validator { */ private Collection<Pattern> subjectDNPatterns = new ArrayList<Pattern>(); - - /** - * Set the time in seconds in the future within which the NotBefore time of an incoming - * Assertion is valid. The default is 60 seconds. - */ - public void setFutureTTL(int newFutureTTL) { - futureTTL = newFutureTTL; - } - - /** - * Set the kind of trust. The default is CHAIN_TRUST. - */ - public void setSignatureTrustType(TRUST_TYPE trustType) { - this.signatureTrustType = trustType; - } - /** * Set a list of Strings corresponding to regular expression constraints on * the subject DN of a certificate @@ -98,53 +56,12 @@ public class SamlAssertionValidator implements Validator { } /** - * Validate the credential argument. It must contain a non-null AssertionWrapper. - * A Crypto and a CallbackHandler implementation is also required to be set. - * - * @param credential the Credential to be validated - * @param data the RequestData associated with the request - * @throws WSSecurityException on a failed validation + * Set the kind of trust. The default is CHAIN_TRUST. */ - public Credential validate(Credential credential, RequestData data) throws WSSecurityException { - if (credential == null || credential.getSamlAssertion() == null) { - throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noCredential"); - } - SamlAssertionWrapper assertion = credential.getSamlAssertion(); - - // Check HOK requirements - String confirmMethod = null; - List<String> methods = assertion.getConfirmationMethods(); - if (methods != null && methods.size() > 0) { - confirmMethod = methods.get(0); - } - if (OpenSAMLUtil.isMethodHolderOfKey(confirmMethod)) { - if (assertion.getSubjectKeyInfo() == null) { - LOG.debug("There is no Subject KeyInfo to match the holder-of-key subject conf method"); - throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noKeyInSAMLToken"); - } - // The assertion must have been signed for HOK - if (!assertion.isSigned()) { - LOG.debug("A holder-of-key assertion must be signed"); - throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity"); - } - } - - // Check conditions - checkConditions(assertion); - - // Check OneTimeUse Condition - checkOneTimeUse(assertion, data); - - // Validate the assertion against schemas/profiles - validateAssertion(assertion); - - // Verify trust on the signature - if (assertion.isSigned()) { - verifySignedAssertion(assertion, data); - } - return credential; + public void setSignatureTrustType(TRUST_TYPE trustType) { + this.signatureTrustType = trustType; } - + /** * Verify trust in the signature of a signed Assertion. This method is separate so that * the user can override if if they want. @@ -153,6 +70,7 @@ public class SamlAssertionValidator implements Validator { * @return A Credential instance * @throws WSSecurityException */ + @Override protected Credential verifySignedAssertion( SamlAssertionWrapper assertion, RequestData data @@ -169,73 +87,5 @@ public class SamlAssertionValidator implements Validator { return trustValidator.validate(credential, data); } - protected Crypto getCrypto(RequestData data) { - return data.getSigVerCrypto(); - } - - /** - * Check the Conditions of the Assertion. - */ - protected void checkConditions(SamlAssertionWrapper samlAssertion) throws WSSecurityException { - samlAssertion.checkConditions(futureTTL); - } - - /** - * Check the "OneTimeUse" Condition of the Assertion. If this is set then the Assertion - * is cached (if a cache is defined), and must not have been previously cached - */ - protected void checkOneTimeUse( - SamlAssertionWrapper samlAssertion, RequestData data - ) throws WSSecurityException { - if (samlAssertion.getSamlVersion().equals(SAMLVersion.VERSION_20) - && samlAssertion.getSaml2().getConditions() != null - && samlAssertion.getSaml2().getConditions().getOneTimeUse() != null - && data.getSamlOneTimeUseReplayCache() != null) { - String identifier = samlAssertion.getId(); - - ReplayCache replayCache = data.getSamlOneTimeUseReplayCache(); - if (replayCache.contains(identifier)) { - throw new WSSecurityException( - WSSecurityException.ErrorCode.INVALID_SECURITY, - "badSamlToken", - "A replay attack has been detected"); - } - - DateTime expires = samlAssertion.getSaml2().getConditions().getNotOnOrAfter(); - if (expires != null) { - Date rightNow = new Date(); - long currentTime = rightNow.getTime(); - long expiresTime = expires.getMillis(); - replayCache.add(identifier, 1L + (expiresTime - currentTime) / 1000L); - } else { - replayCache.add(identifier); - } - - replayCache.add(identifier); - } - } - - /** - * Validate the samlAssertion against schemas/profiles - */ - protected void validateAssertion(SamlAssertionWrapper samlAssertion) throws WSSecurityException { - samlAssertion.validateAssertion(validateSignatureAgainstProfile); - } - - /** - * Whether to validate the signature of the Assertion (if it exists) against the - * relevant profile. Default is true. - */ - public boolean isValidateSignatureAgainstProfile() { - return validateSignatureAgainstProfile; - } - - /** - * Whether to validate the signature of the Assertion (if it exists) against the - * relevant profile. Default is true. - */ - public void setValidateSignatureAgainstProfile(boolean validateSignatureAgainstProfile) { - this.validateSignatureAgainstProfile = validateSignatureAgainstProfile; - } } http://git-wip-us.apache.org/repos/asf/cxf-fediz/blob/70b5a85b/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index d29e32a..a226e92 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ <spring.version>3.2.6.RELEASE</spring.version> <spring.security.version>3.1.4.RELEASE</spring.security.version> <tomcat.version>7.0.54</tomcat.version> - <wss4j.version>2.0.2</wss4j.version> + <wss4j.version>2.0.3-SNAPSHOT</wss4j.version> <xalan.version>2.7.2</xalan.version> <bval.version>0.5</bval.version>
