You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2015/01/16 12:40:01 UTC
svn commit: r1652392 - in /webservices/wss4j/branches/1_6_x-fixes/src:
main/java/org/apache/ws/security/handler/
main/java/org/apache/ws/security/validate/
test/java/org/apache/ws/security/saml/
Author: coheigea
Date: Fri Jan 16 11:40:01 2015
New Revision: 1652392
URL: http://svn.apache.org/r1652392
Log:
[WSS-523] - Add the ability to supply AudienceRestrictions when validating SAML tokens - DOM part
Conflicts:
src/main/java/org/apache/ws/security/handler/RequestData.java
src/main/java/org/apache/ws/security/saml/ext/AssertionWrapper.java
src/main/java/org/apache/ws/security/validate/SamlAssertionValidator.java
src/test/java/org/apache/ws/security/saml/SamlConditionsTest.java
Modified:
webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java
webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/validate/SamlAssertionValidator.java
webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SamlConditionsTest.java
Modified: webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java?rev=1652392&r1=1652391&r2=1652392&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java Fri Jan 16 11:40:01 2015
@@ -91,6 +91,7 @@ public class RequestData {
private int originalSignatureActionPosition;
private AlgorithmSuite algorithmSuite;
private AlgorithmSuite samlAlgorithmSuite;
+ private final List<String> audienceRestrictions = new ArrayList<String>();
public void clear() {
soapConstants = null;
@@ -122,6 +123,7 @@ public class RequestData {
algorithmSuite = null;
samlAlgorithmSuite = null;
setOriginalSignatureActionPosition(0);
+ audienceRestrictions.clear();
}
public String getSignatureC14nAlgorithm() {
@@ -547,7 +549,23 @@ public class RequestData {
public Collection<Pattern> getSubjectCertConstraints() {
return subjectDNPatterns;
}
-
+
+ /**
+ * Set the Audience Restrictions
+ */
+ public void setAudienceRestrictions(List<String> audienceRestrictions) {
+ if (audienceRestrictions != null) {
+ this.audienceRestrictions.addAll(audienceRestrictions);
+ }
+ }
+
+ /**
+ * Get the Audience Restrictions
+ */
+ public List<String> getAudienceRestrictions() {
+ return audienceRestrictions;
+ }
+
public boolean isAppendSignatureAfterTimestamp() {
return appendSignatureAfterTimestamp;
}
Modified: webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/validate/SamlAssertionValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/validate/SamlAssertionValidator.java?rev=1652392&r1=1652391&r2=1652392&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/validate/SamlAssertionValidator.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/validate/SamlAssertionValidator.java Fri Jan 16 11:40:01 2015
@@ -106,8 +106,11 @@ public class SamlAssertionValidator exte
// Check conditions
checkConditions(assertion);
-
- // Check the AuthnStatements of the Assertion (if any)
+
+ // Check the audience restrictions
+ checkAudienceRestrictions(assertion, data.getAudienceRestrictions());
+
+ // Check the AuthnStatements of the assertion (if any)
checkAuthnStatements(assertion);
// Check OneTimeUse Condition
@@ -257,6 +260,70 @@ public class SamlAssertionValidator exte
}
}
}
+
+ /**
+ * Check the AudienceRestrictions of the Assertion
+ */
+ public void checkAudienceRestrictions(
+ AssertionWrapper assertion, List<String> audienceRestrictions
+ ) throws WSSecurityException {
+ // Now check the audience restriction conditions
+ if (audienceRestrictions == null || audienceRestrictions.isEmpty()) {
+ return;
+ }
+
+ if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_20)
+ && assertion.getSaml2().getConditions() != null) {
+ org.opensaml.saml2.core.Conditions conditions =
+ assertion.getSaml2().getConditions();
+ if (conditions != null && conditions.getAudienceRestrictions() != null) {
+ boolean foundAddress = false;
+ for (org.opensaml.saml2.core.AudienceRestriction audienceRestriction
+ : conditions.getAudienceRestrictions()) {
+ if (audienceRestriction.getAudiences() != null) {
+ List<org.opensaml.saml2.core.Audience> audiences =
+ audienceRestriction.getAudiences();
+ for (org.opensaml.saml2.core.Audience audience : audiences) {
+ String audienceURI = audience.getAudienceURI();
+ if (audienceRestrictions.contains(audienceURI)) {
+ foundAddress = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!foundAddress) {
+ throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
+ }
+ }
+ } else if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_11)
+ && assertion.getSaml1().getConditions() != null) {
+ org.opensaml.saml1.core.Conditions conditions =
+ assertion.getSaml1().getConditions();
+ if (conditions != null && conditions.getAudienceRestrictionConditions() != null) {
+ boolean foundAddress = false;
+ for (org.opensaml.saml1.core.AudienceRestrictionCondition audienceRestriction
+ : conditions.getAudienceRestrictionConditions()) {
+ if (audienceRestriction.getAudiences() != null) {
+ List<org.opensaml.saml1.core.Audience> audiences =
+ audienceRestriction.getAudiences();
+ for (org.opensaml.saml1.core.Audience audience : audiences) {
+ String audienceURI = audience.getUri();
+ if (audienceRestrictions.contains(audienceURI)) {
+ foundAddress = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!foundAddress) {
+ throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity");
+ }
+ }
+ }
+ }
/**
* Check the AuthnStatements of the Assertion (if any)
Modified: webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SamlConditionsTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SamlConditionsTest.java?rev=1652392&r1=1652391&r2=1652392&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SamlConditionsTest.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SamlConditionsTest.java Fri Jan 16 11:40:01 2015
@@ -32,6 +32,7 @@ import org.apache.ws.security.common.Cus
import org.apache.ws.security.common.SAML1CallbackHandler;
import org.apache.ws.security.common.SAML2CallbackHandler;
import org.apache.ws.security.common.SOAPUtil;
+import org.apache.ws.security.handler.RequestData;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecSAMLToken;
import org.apache.ws.security.saml.ext.AssertionWrapper;
@@ -42,6 +43,7 @@ import org.apache.ws.security.saml.ext.b
import org.apache.ws.security.util.WSSecurityUtil;
import org.joda.time.DateTime;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
/**
* Test-case for sending and processing an a SAML Token with a custom Conditions element.
@@ -507,6 +509,133 @@ public class SamlConditionsTest extends
verify(unsignedDoc);
}
+ // Now test AudienceRestrictions with supplied restrictions
+ @org.junit.Test
+ public void testSAML2AudienceRestrictionVerification() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("www.example.com");
+
+ ConditionsBean conditions = new ConditionsBean();
+ conditions.setTokenPeriodMinutes(5);
+ List<String> audiences = new ArrayList<String>();
+ audiences.add("http://apache.org/one");
+ audiences.add("http://apache.org/two");
+ AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
+ audienceRestrictionBean.setAudienceURIs(audiences);
+ conditions.setAudienceRestrictions(Collections.singletonList(audienceRestrictionBean));
+
+ callbackHandler.setConditions(conditions);
+
+ SAMLParms samlParms = new SAMLParms();
+ samlParms.setCallbackHandler(callbackHandler);
+ AssertionWrapper assertion = new AssertionWrapper(samlParms);
+
+ WSSecSAMLToken wsSign = new WSSecSAMLToken();
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
+
+ String outputString =
+ org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
+ assertTrue(outputString.contains("AudienceRestriction"));
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(outputString);
+ }
+
+ // This should fail as the expected audience isn't in the assertion
+ audiences.clear();
+ audiences.add("http://apache.org/three");
+
+ WSSecurityEngine newEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setAudienceRestrictions(audiences);
+
+ Element securityHeader =
+ WSSecurityUtil.findWsseSecurityHeaderBlock(unsignedDoc,
+ unsignedDoc.getDocumentElement(),
+ false);
+ try {
+ newEngine.processSecurityHeader(securityHeader, data);
+ fail("Failure expected on a bad audience restriction");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ // Now add the correct audience back in...
+ audiences.add("http://apache.org/one");
+ data.setAudienceRestrictions(audiences);
+
+ newEngine.processSecurityHeader(securityHeader, data);
+ }
+
+ // Now test AudienceRestrictions with supplied restrictions
+ @org.junit.Test
+ public void testSAML1AudienceRestrictionVerification() throws Exception {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("www.example.com");
+
+ ConditionsBean conditions = new ConditionsBean();
+ conditions.setTokenPeriodMinutes(5);
+ List<String> audiences = new ArrayList<String>();
+ audiences.add("http://apache.org/one");
+ audiences.add("http://apache.org/two");
+ AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
+ audienceRestrictionBean.setAudienceURIs(audiences);
+ conditions.setAudienceRestrictions(Collections.singletonList(audienceRestrictionBean));
+
+ callbackHandler.setConditions(conditions);
+
+ SAMLParms samlParms = new SAMLParms();
+ samlParms.setCallbackHandler(callbackHandler);
+ AssertionWrapper assertion = new AssertionWrapper(samlParms);
+
+ WSSecSAMLToken wsSign = new WSSecSAMLToken();
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
+
+ String outputString =
+ org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
+ assertTrue(outputString.contains("AudienceRestriction"));
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(outputString);
+ }
+
+ // This should fail as the expected audience isn't in the assertion
+ audiences.clear();
+ audiences.add("http://apache.org/three");
+
+ WSSecurityEngine newEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setAudienceRestrictions(audiences);
+
+ Element securityHeader =
+ WSSecurityUtil.findWsseSecurityHeaderBlock(unsignedDoc,
+ unsignedDoc.getDocumentElement(),
+ false);
+
+ try {
+ newEngine.processSecurityHeader(securityHeader, data);
+ fail("Failure expected on a bad audience restriction");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ // Now add the correct audience back in...
+ audiences.add("http://apache.org/one");
+ data.setAudienceRestrictions(audiences);
+
+ newEngine.processSecurityHeader(securityHeader, data);
+ }
+
/**
* Test that creates, sends and processes an unsigned SAML 2 authentication assertion
* with two AudienceRestriction Elements
@@ -556,6 +685,76 @@ public class SamlConditionsTest extends
verify(unsignedDoc);
}
+ // Now test AudienceRestrictions with supplied restrictions
+ @org.junit.Test
+ public void testSAML2AudienceRestrictionSeparateRestrictionsValidation() throws Exception {
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+ callbackHandler.setIssuer("www.example.com");
+
+ ConditionsBean conditions = new ConditionsBean();
+ conditions.setTokenPeriodMinutes(5);
+
+ List<AudienceRestrictionBean> audiencesRestrictions =
+ new ArrayList<AudienceRestrictionBean>();
+ AudienceRestrictionBean audienceRestrictionBean = new AudienceRestrictionBean();
+ audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/one"));
+ audiencesRestrictions.add(audienceRestrictionBean);
+
+ audienceRestrictionBean = new AudienceRestrictionBean();
+ audienceRestrictionBean.setAudienceURIs(Collections.singletonList("http://apache.org/two"));
+ audiencesRestrictions.add(audienceRestrictionBean);
+
+ conditions.setAudienceRestrictions(audiencesRestrictions);
+
+ callbackHandler.setConditions(conditions);
+
+ SAMLParms samlParms = new SAMLParms();
+ samlParms.setCallbackHandler(callbackHandler);
+ AssertionWrapper assertion = new AssertionWrapper(samlParms);
+
+ WSSecSAMLToken wsSign = new WSSecSAMLToken();
+
+ Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+ WSSecHeader secHeader = new WSSecHeader();
+ secHeader.insertSecurityHeader(doc);
+
+ Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
+
+ String outputString =
+ org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
+ assertTrue(outputString.contains("AudienceRestriction"));
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(outputString);
+ }
+
+ // This should fail as the expected audience isn't in the assertion
+ List<String> audiences = new ArrayList<String>();
+ audiences.add("http://apache.org/three");
+
+ WSSecurityEngine newEngine = new WSSecurityEngine();
+ RequestData data = new RequestData();
+ data.setAudienceRestrictions(audiences);
+
+ Element securityHeader =
+ WSSecurityUtil.findWsseSecurityHeaderBlock(unsignedDoc,
+ unsignedDoc.getDocumentElement(),
+ false);
+
+ try {
+ newEngine.processSecurityHeader(securityHeader, data);
+ fail("Failure expected on a bad audience restriction");
+ } catch (WSSecurityException ex) {
+ // expected
+ }
+
+ // Now add the correct audience back in...
+ audiences.add("http://apache.org/one");
+ data.setAudienceRestrictions(audiences);
+
+ newEngine.processSecurityHeader(securityHeader, data);
+ }
+
/**
* Verifies the soap envelope
* <p/>