You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2012/05/23 17:14:45 UTC
svn commit: r1341892 - in /cxf/fediz/trunk/plugins/core/src:
main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
Author: coheigea
Date: Wed May 23 15:14:45 2012
New Revision: 1341892
URL: http://svn.apache.org/viewvc?rev=1341892&view=rev
Log:
Validating Assertions against specs + checking conditions in the SAMLTokenValidator
Modified:
cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
Modified: cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java?rev=1341892&r1=1341891&r2=1341892&view=diff
==============================================================================
--- cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java (original)
+++ cxf/fediz/trunk/plugins/core/src/main/java/org/apache/cxf/fediz/core/saml/SAMLTokenValidator.java Wed May 23 15:14:45 2012
@@ -45,6 +45,7 @@ import org.apache.cxf.fediz.core.config.
import org.apache.cxf.fediz.core.config.KeyStore;
import org.apache.cxf.fediz.core.config.TrustManager;
import org.apache.cxf.fediz.core.config.TrustedIssuer;
+
import org.apache.ws.security.SAMLTokenPrincipal;
import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSPasswordCallback;
@@ -57,8 +58,11 @@ import org.apache.ws.security.saml.SAMLK
import org.apache.ws.security.saml.ext.AssertionWrapper;
import org.apache.ws.security.validate.Credential;
import org.apache.ws.security.validate.SignatureTrustValidator;
+import org.joda.time.DateTime;
import org.opensaml.common.SAMLVersion;
import org.opensaml.xml.XMLObject;
+import org.opensaml.xml.validation.ValidationException;
+import org.opensaml.xml.validation.ValidatorSuite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -66,6 +70,12 @@ import org.slf4j.LoggerFactory;
public class SAMLTokenValidator implements TokenValidator {
private static final Logger LOG = LoggerFactory.getLogger(SAMLTokenValidator.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;
// [TODO] make sure we answer true only for cases we actually can handle
@Override
@@ -77,6 +87,14 @@ public class SAMLTokenValidator implemen
public boolean canHandleToken(Element token) {
return true;
}
+
+ /**
+ * 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;
+ }
public TokenValidatorResponse validateAndProcessToken(Element token,
FederationContext config) {
@@ -118,6 +136,16 @@ public class SAMLTokenValidator implemen
// Verify the signature
assertion.verifySignature(requestData,
new WSDocInfo(token.getOwnerDocument()));
+
+ // Validate the assertion against schemas/profiles
+ validateAssertion(assertion);
+
+ // Validate Conditions
+ if (config.isDetectExpiredTokens() && !validateConditions(assertion)) {
+ throw new RuntimeException(
+ "Error in validating conditions of the received Assertion"
+ );
+ }
// Now verify trust on the signature
Credential trustCredential = new Credential();
@@ -370,6 +398,67 @@ public class SAMLTokenValidator implemen
truststoreFile);
return p;
}
+
+ /**
+ * Validate the assertion against schemas/profiles
+ */
+ protected void validateAssertion(AssertionWrapper assertion) throws WSSecurityException {
+ if (assertion.getSaml1() != null) {
+ ValidatorSuite schemaValidators =
+ org.opensaml.Configuration.getValidatorSuite("saml1-schema-validator");
+ ValidatorSuite specValidators =
+ org.opensaml.Configuration.getValidatorSuite("saml1-spec-validator");
+ try {
+ schemaValidators.validate(assertion.getSaml1());
+ specValidators.validate(assertion.getSaml1());
+ } catch (ValidationException e) {
+ LOG.debug("Saml Validation error: " + e.getMessage());
+ throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
+ }
+ } else if (assertion.getSaml2() != null) {
+ ValidatorSuite schemaValidators =
+ org.opensaml.Configuration.getValidatorSuite("saml2-core-schema-validator");
+ ValidatorSuite specValidators =
+ org.opensaml.Configuration.getValidatorSuite("saml2-core-spec-validator");
+ try {
+ schemaValidators.validate(assertion.getSaml2());
+ specValidators.validate(assertion.getSaml2());
+ } catch (ValidationException e) {
+ LOG.debug("Saml Validation error: " + e.getMessage());
+ throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
+ }
+ }
+ }
+
+ protected boolean validateConditions(
+ AssertionWrapper assertion
+ ) {
+ DateTime validFrom = null;
+ DateTime validTill = null;
+ if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_20)) {
+ validFrom = assertion.getSaml2().getConditions().getNotBefore();
+ validTill = assertion.getSaml2().getConditions().getNotOnOrAfter();
+ } else {
+ validFrom = assertion.getSaml1().getConditions().getNotBefore();
+ validTill = assertion.getSaml1().getConditions().getNotOnOrAfter();
+ }
+
+ if (validFrom != null) {
+ DateTime currentTime = new DateTime();
+ currentTime = currentTime.plusSeconds(futureTTL);
+ if (validFrom.isAfter(currentTime)) {
+ LOG.warn("SAML Token condition (Not Before) not met");
+ return false;
+ }
+ }
+
+ if (validTill != null && validTill.isBeforeNow()) {
+ LOG.debug("SAML Token condition (Not On Or After) not met");
+ return false;
+ }
+
+ return true;
+ }
// A sample MyHandler class
class PasswordCallbackHandler implements CallbackHandler {
Modified: cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java
URL: http://svn.apache.org/viewvc/cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java?rev=1341892&r1=1341891&r2=1341892&view=diff
==============================================================================
--- cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java (original)
+++ cxf/fediz/trunk/plugins/core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java Wed May 23 15:14:45 2012
@@ -129,6 +129,7 @@ public class FederationProcessorTest {
wfReq.setWresult(sRSTR);
FederationContext config = loadRootConfig();
config.setDetectReplayedTokens(false);
+ config.setDetectExpiredTokens(false);
FederationProcessor wfProc = new FederationProcessorImpl();
FederationResponse wfRes = wfProc.processRequest(wfReq, config);
@@ -145,6 +146,7 @@ public class FederationProcessorTest {
wfReq.setWresult(sRSTR);
FederationContext config = loadOtherIssuerRootConfig();
config.setDetectReplayedTokens(false);
+ config.setDetectExpiredTokens(false);
FederationProcessor wfProc = new FederationProcessorImpl();
try {
wfProc.processRequest(wfReq, config);
@@ -164,6 +166,7 @@ public class FederationProcessorTest {
FederationContext config = loadRootConfig();
config.setDetectReplayedTokens(false);
+ config.setDetectExpiredTokens(false);
FederationProcessor wfProc = new FederationProcessorImpl();
FederationResponse wfRes = wfProc.processRequest(wfReq, config);
@@ -181,6 +184,7 @@ public class FederationProcessorTest {
wfReq.setWa(FederationConstants.ACTION_SIGNIN);
wfReq.setWresult(sRSTRREPLAY);
FederationContext config = loadRootConfig();
+ config.setDetectExpiredTokens(false);
FederationProcessor wfProc = new FederationProcessorImpl();
FederationResponse wfRes = wfProc.processRequest(wfReq, config);