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 2014/09/10 18:19:57 UTC
svn commit: r1624053 - in /webservices/wss4j/branches/1_6_x-fixes/src:
main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
Author: coheigea
Date: Wed Sep 10 16:19:56 2014
New Revision: 1624053
URL: http://svn.apache.org/r1624053
Log:
Record SAML Token signed results so that it can be used in SignedElements evaluation.
Conflicts:
src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
Modified:
webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
Modified: webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java?rev=1624053&r1=1624052&r2=1624053&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java Wed Sep 10 16:19:56 2014
@@ -21,6 +21,7 @@ package org.apache.ws.security.processor
import org.apache.ws.security.SAMLTokenPrincipal;
import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDataRef;
import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
@@ -33,16 +34,18 @@ import org.apache.ws.security.saml.ext.A
import org.apache.ws.security.util.DOM2Writer;
import org.apache.ws.security.validate.Credential;
import org.apache.ws.security.validate.Validator;
-
import org.opensaml.xml.signature.KeyInfo;
import org.opensaml.xml.signature.Signature;
import org.w3c.dom.Element;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
+import java.util.ArrayList;
import java.util.List;
import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.XMLValidateContext;
@@ -75,15 +78,22 @@ public class SAMLTokenProcessor implemen
Validator validator =
data.getValidator(new QName(elem.getNamespaceURI(), elem.getLocalName()));
- Credential credential = handleSAMLToken(elem, data, validator, wsDocInfo);
- AssertionWrapper assertion = credential.getAssertion();
+
+ AssertionWrapper samlAssertion = new AssertionWrapper(elem);
+ XMLSignature xmlSignature =
+ verifySignatureKeysAndAlgorithms(samlAssertion, data, wsDocInfo);
+ List<WSDataRef> dataRefs = createDataRefs(elem, samlAssertion, xmlSignature);
+
+ Credential credential =
+ handleSAMLToken(samlAssertion, data, validator, wsDocInfo);
+ samlAssertion = credential.getAssertion();
if (log.isDebugEnabled()) {
- log.debug("SAML Assertion issuer " + assertion.getIssuerString());
+ log.debug("SAML Assertion issuer " + samlAssertion.getIssuerString());
log.debug(DOM2Writer.nodeToString(elem));
}
// See if the token has been previously processed
- String id = assertion.getId();
+ String id = samlAssertion.getId();
Element foundElement = wsDocInfo.getTokenElement(id);
if (elem.equals(foundElement)) {
WSSecurityEngineResult result = wsDocInfo.getResult(id);
@@ -96,10 +106,11 @@ public class SAMLTokenProcessor implemen
wsDocInfo.addTokenElement(elem);
WSSecurityEngineResult result = null;
- if (assertion.isSigned()) {
- result = new WSSecurityEngineResult(WSConstants.ST_SIGNED, assertion);
+ if (samlAssertion.isSigned()) {
+ result = new WSSecurityEngineResult(WSConstants.ST_SIGNED, samlAssertion);
+ result.put(WSSecurityEngineResult.TAG_DATA_REF_URIS, dataRefs);
} else {
- result = new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, assertion);
+ result = new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, samlAssertion);
}
if (!"".equals(id)) {
@@ -122,7 +133,7 @@ public class SAMLTokenProcessor implemen
} else if (credential.getPrincipal() != null) {
result.put(WSSecurityEngineResult.TAG_PRINCIPAL, credential.getPrincipal());
} else {
- result.put(WSSecurityEngineResult.TAG_PRINCIPAL, new SAMLTokenPrincipal(assertion));
+ result.put(WSSecurityEngineResult.TAG_PRINCIPAL, new SAMLTokenPrincipal(samlAssertion));
}
result.put(WSSecurityEngineResult.TAG_SUBJECT, credential.getSubject());
}
@@ -131,17 +142,30 @@ public class SAMLTokenProcessor implemen
}
public Credential handleSAMLToken(
- Element token,
+ AssertionWrapper samlAssertion,
RequestData data,
Validator validator,
WSDocInfo docInfo
) throws WSSecurityException {
- AssertionWrapper assertion = new AssertionWrapper(token);
- if (assertion.isSigned()) {
- // Check for compliance against the defined AlgorithmSuite
- AlgorithmSuite algorithmSuite = data.getSamlAlgorithmSuite();
+ // Parse the subject if it exists
+ samlAssertion.parseHOKSubject(data, docInfo);
- Signature sig = assertion.getSignature();
+ // Now delegate the rest of the verification to the Validator
+ Credential credential = new Credential();
+ credential.setAssertion(samlAssertion);
+ if (validator != null) {
+ return validator.validate(credential, data);
+ }
+ return credential;
+ }
+
+ private XMLSignature verifySignatureKeysAndAlgorithms(
+ AssertionWrapper samlAssertion,
+ RequestData data,
+ WSDocInfo wsDocInfo
+ ) throws WSSecurityException {
+ if (samlAssertion.isSigned()) {
+ Signature sig = samlAssertion.getSignature();
KeyInfo keyInfo = sig.getKeyInfo();
if (keyInfo == null) {
throw new WSSecurityException(
@@ -151,57 +175,92 @@ public class SAMLTokenProcessor implemen
}
SAMLKeyInfo samlKeyInfo =
SAMLUtil.getCredentialFromKeyInfo(
- keyInfo.getDOM(), data, docInfo, data.getWssConfig().isWsiBSPCompliant()
+ keyInfo.getDOM(), data, wsDocInfo, data.getWssConfig().isWsiBSPCompliant()
+ );
+
+ PublicKey key = null;
+ if (samlKeyInfo.getCerts() != null && samlKeyInfo.getCerts()[0] != null) {
+ key = samlKeyInfo.getCerts()[0].getPublicKey();
+ } else if (samlKeyInfo.getPublicKey() != null) {
+ key = samlKeyInfo.getPublicKey();
+ } else {
+ throw new WSSecurityException(
+ WSSecurityException.FAILURE, "invalidSAMLsecurity",
+ new Object[]{"cannot get certificate or key"}
+ );
+ }
+
+ // Not checking signature here, just marshalling into an XMLSignature
+ // structure for testing the transform/digest algorithms etc.
+ XMLValidateContext context = new DOMValidateContext(key, sig.getDOM());
+ context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+ context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+
+ XMLSignature xmlSignature;
+ try {
+ xmlSignature = signatureFactory.unmarshalXMLSignature(context);
+ } catch (MarshalException ex) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_CHECK, "invalidSAMLsecurity",
+ new Object[]{"cannot get certificate or key"}, ex
);
+ }
+ // Check for compliance against the defined AlgorithmSuite
+ AlgorithmSuite algorithmSuite = data.getSamlAlgorithmSuite();
if (algorithmSuite != null) {
AlgorithmSuiteValidator algorithmSuiteValidator = new
AlgorithmSuiteValidator(algorithmSuite);
- PublicKey key = null;
- if (samlKeyInfo.getCerts() != null && samlKeyInfo.getCerts()[0] != null) {
- key = samlKeyInfo.getCerts()[0].getPublicKey();
- } else if (samlKeyInfo.getPublicKey() != null) {
- key = samlKeyInfo.getPublicKey();
- } else {
- throw new WSSecurityException(
- WSSecurityException.FAILURE, "invalidSAMLsecurity",
- new Object[]{"cannot get certificate or key"}
- );
- }
-
- // Not checking signature here, just marshalling into an XMLSignature
- // structure for testing the transform/digest algorithms etc.
- XMLValidateContext context = new DOMValidateContext(key, sig.getDOM());
- context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
- context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
-
- XMLSignature xmlSignature;
- try {
- xmlSignature = signatureFactory.unmarshalXMLSignature(context);
- } catch (MarshalException ex) {
- throw new WSSecurityException(
- WSSecurityException.FAILED_CHECK, "invalidSAMLsecurity",
- new Object[]{"cannot get certificate or key"}, ex
- );
- }
-
algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
algorithmSuiteValidator.checkAsymmetricKeyLength(key);
}
- assertion.verifySignature(samlKeyInfo);
- }
- // Parse the HOK subject if it exists
- assertion.parseHOKSubject(data, docInfo);
+ samlAssertion.verifySignature(samlKeyInfo);
- // Now delegate the rest of the verification to the Validator
- Credential credential = new Credential();
- credential.setAssertion(assertion);
- if (validator != null) {
- return validator.validate(credential, data);
+ return xmlSignature;
}
- return credential;
+
+ return null;
}
+ private List<WSDataRef> createDataRefs(
+ Element token, AssertionWrapper samlAssertion, XMLSignature xmlSignature
+ ) {
+ if (xmlSignature == null) {
+ return null;
+ }
+
+ List<WSDataRef> protectedRefs = new ArrayList<WSDataRef>();
+ String signatureMethod =
+ xmlSignature.getSignedInfo().getSignatureMethod().getAlgorithm();
+
+ for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
+ Reference reference = (Reference)refObject;
+
+ if ("".equals(reference.getURI())
+ || reference.getURI().equals(samlAssertion.getId())
+ || reference.getURI().equals("#" + samlAssertion.getId())) {
+ WSDataRef ref = new WSDataRef();
+ ref.setWsuId(reference.getURI());
+ ref.setProtectedElement(token);
+ ref.setAlgorithm(signatureMethod);
+ ref.setDigestAlgorithm(reference.getDigestMethod().getAlgorithm());
+
+ // Set the Transform algorithms as well
+ @SuppressWarnings("unchecked")
+ List<Transform> transforms = (List<Transform>)reference.getTransforms();
+ List<String> transformAlgorithms = new ArrayList<String>(transforms.size());
+ for (Transform transform : transforms) {
+ transformAlgorithms.add(transform.getAlgorithm());
+ }
+ ref.setTransformAlgorithms(transformAlgorithms);
+
+ ref.setXpath(ReferenceListProcessor.getXPath(token));
+ protectedRefs.add(ref);
+ }
+ }
+
+ return protectedRefs;
+ }
}
Modified: webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java?rev=1624053&r1=1624052&r2=1624053&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java Wed Sep 10 16:19:56 2014
@@ -130,16 +130,24 @@ public class SignedSamlTokenHOKTest exte
assertTrue(receivedAssertion.isSigned());
assertTrue(receivedAssertion.getSignatureValue() != null);
+ // Test we have a WSDataRef for the signed SAML token as well
+ List<WSDataRef> refs =
+ (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+ assertTrue(refs.size() == 1);
+
+ WSDataRef wsDataRef = refs.get(0);
+ String xpath = wsDataRef.getXpath();
+ assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion", xpath);
+
// Test we processed a signature (SOAP body)
actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
assertTrue(actionResult != null);
assertFalse(actionResult.isEmpty());
- final List<WSDataRef> refs =
- (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+ refs = (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
assertTrue(refs.size() == 1);
- WSDataRef wsDataRef = (WSDataRef)refs.get(0);
- String xpath = wsDataRef.getXpath();
+ wsDataRef = refs.get(0);
+ xpath = wsDataRef.getXpath();
assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
}