You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by gi...@apache.org on 2012/12/08 18:41:52 UTC
svn commit: r1418719 - in /webservices/wss4j/trunk/ws-security-stax/src:
main/java/org/apache/ws/security/stax/ext/
main/java/org/apache/ws/security/stax/impl/processor/input/
main/java/org/apache/ws/security/stax/impl/securityToken/
test/java/org/apac...
Author: giger
Date: Sat Dec 8 17:41:50 2012
New Revision: 1418719
URL: http://svn.apache.org/viewvc?rev=1418719&view=rev
Log:
WSS-373 - Check sender-vouches and holder-of-key requirements for SAML tokens.
Modified:
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java
webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java
webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java
Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java Sat Dec 8 17:41:50 2012
@@ -28,13 +28,17 @@ import org.apache.ws.security.stax.impl.
import org.apache.ws.security.stax.securityEvent.WSSecurityEventConstants;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.ext.InputProcessor;
+import org.apache.xml.security.stax.ext.SecurityToken;
+import org.apache.xml.security.stax.ext.SecurityTokenProvider;
import org.apache.xml.security.stax.impl.DocumentContextImpl;
import org.apache.xml.security.stax.impl.InputProcessorChainImpl;
import org.apache.xml.security.stax.impl.XMLSecurityStreamReader;
import org.apache.xml.security.stax.impl.processor.input.LogInputProcessor;
import org.apache.xml.security.stax.impl.processor.input.XMLEventReaderInputProcessor;
+import org.apache.xml.security.stax.impl.util.IDGenerator;
import org.apache.xml.security.stax.securityEvent.SecurityEvent;
import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
+import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
@@ -133,10 +137,36 @@ public class InboundWSSec {
Iterator<SecurityEvent> securityEventIterator = requestSecurityEvents.iterator();
while (securityEventIterator.hasNext()) {
SecurityEvent securityEvent = securityEventIterator.next();
- if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.HttpsToken) {
- securityContextImpl.registerSecurityEvent(securityEvent);
- securityContextImpl.put(WSSConstants.TRANSPORT_SECURITY_ACTIVE, Boolean.TRUE);
- break;
+ if (securityEvent instanceof TokenSecurityEvent) {
+ final TokenSecurityEvent tokenSecurityEvent = (TokenSecurityEvent)securityEvent;
+
+ if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.HttpsToken) {
+ securityContextImpl.registerSecurityEvent(securityEvent);
+ securityContextImpl.put(WSSConstants.TRANSPORT_SECURITY_ACTIVE, Boolean.TRUE);
+ }
+
+ SecurityTokenProvider securityTokenProvider = new SecurityTokenProvider() {
+
+ private String id;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public SecurityToken getSecurityToken() throws XMLSecurityException {
+ return tokenSecurityEvent.getSecurityToken();
+ }
+
+ @Override
+ public String getId() {
+ if (this.id == null) {
+ this.id = tokenSecurityEvent.getSecurityToken().getId();
+ if (this.id == null) {
+ this.id = IDGenerator.generateID(null);
+ }
+ }
+ return this.id;
+ }
+ };
+ securityContextImpl.registerSecurityTokenProvider(securityTokenProvider.getId(), securityTokenProvider);
}
}
} catch (XMLSecurityException e) {
Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java Sat Dec 8 17:41:50 2012
@@ -29,6 +29,7 @@ import org.apache.ws.security.common.sam
import org.apache.ws.security.common.saml.SAMLUtil;
import org.apache.ws.security.stax.ext.WSSConstants;
import org.apache.ws.security.stax.ext.WSSSecurityProperties;
+import org.apache.ws.security.stax.ext.WSSUtils;
import org.apache.ws.security.stax.ext.WSSecurityContext;
import org.apache.ws.security.stax.impl.securityToken.SAMLSecurityToken;
import org.apache.ws.security.stax.securityEvent.SamlTokenSecurityEvent;
@@ -46,6 +47,10 @@ import org.apache.xml.security.stax.ext.
import org.apache.xml.security.stax.impl.XMLSecurityEventReader;
import org.apache.xml.security.stax.impl.securityToken.AbstractInboundSecurityToken;
import org.apache.xml.security.stax.impl.securityToken.SecurityTokenFactory;
+import org.apache.xml.security.stax.securityEvent.SecurityEvent;
+import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
+import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
+import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
import org.joda.time.DateTime;
import org.opensaml.common.SAMLVersion;
import org.opensaml.security.SAMLSignatureProfileValidator;
@@ -67,13 +72,14 @@ import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Comment;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.ProcessingInstruction;
import java.security.Key;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.List;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.*;
/**
* Processor for the SAML Assertion XML Structure
@@ -86,8 +92,13 @@ public class SAMLTokenInputHandler exten
private static final transient Log log = LogFactory.getLog(SAMLTokenInputHandler.class);
private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ private static final List<QName> saml1TokenPath = new ArrayList<QName>(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+ private static final List<QName> saml2TokenPath = new ArrayList<QName>(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+
static {
documentBuilderFactory.setNamespaceAware(true);
+ saml1TokenPath.add(WSSConstants.TAG_saml_Assertion);
+ saml2TokenPath.add(WSSConstants.TAG_saml2_Assertion);
}
/**
@@ -260,6 +271,11 @@ public class SAMLTokenInputHandler exten
samlTokenSecurityEvent.setSecurityToken((SecurityToken) securityTokenProvider.getSecurityToken());
samlTokenSecurityEvent.setCorrelationID(samlAssertionWrapper.getId());
inputProcessorChain.getSecurityContext().registerSecurityEvent(samlTokenSecurityEvent);
+
+ SAMLTokenVerifierInputProcessor samlTokenVerifierInputProcessor =
+ new SAMLTokenVerifierInputProcessor(securityProperties, samlAssertionWrapper, securityTokenProvider, subjectSecurityToken);
+ inputProcessorChain.getSecurityContext().addSecurityEventListener(samlTokenVerifierInputProcessor);
+ inputProcessorChain.addProcessor(samlTokenVerifierInputProcessor);
}
private int getSubjectKeyInfoIndex(Deque<XMLSecEvent> eventQueue) {
@@ -614,4 +630,190 @@ public class SAMLTokenInputHandler exten
}
}
}
+
+ /**
+ * Processor to check the holder-of-key or sender-vouches requirements against the received assertion
+ * which can not be done until the whole soap-header is processed and we now that the whole soap-body
+ * is signed.
+ */
+ class SAMLTokenVerifierInputProcessor extends AbstractInputProcessor implements SecurityEventListener {
+
+ private SamlAssertionWrapper samlAssertionWrapper;
+ private SecurityTokenProvider securityTokenProvider;
+ private SecurityToken subjectSecurityToken;
+ private List<SignedElementSecurityEvent> samlTokenSignedElementSecurityEvents = new ArrayList<SignedElementSecurityEvent>();
+ private SignedElementSecurityEvent bodySignedElementSecurityEvent;
+
+ SAMLTokenVerifierInputProcessor(XMLSecurityProperties securityProperties, SamlAssertionWrapper samlAssertionWrapper,
+ SecurityTokenProvider securityTokenProvider, SecurityToken subjectSecurityToken) {
+ super(securityProperties);
+ this.setPhase(XMLSecurityConstants.Phase.POSTPROCESSING);
+ this.addAfterProcessor(OperationInputProcessor.class.getName());
+ this.samlAssertionWrapper = samlAssertionWrapper;
+ this.securityTokenProvider = securityTokenProvider;
+ this.subjectSecurityToken = subjectSecurityToken;
+ }
+
+ @Override
+ public void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
+ if (securityEvent.getSecurityEventType() == SecurityEventConstants.SignedElement) {
+ SignedElementSecurityEvent signedElementSecurityEvent = (SignedElementSecurityEvent)securityEvent;
+
+ List<QName> elementPath = signedElementSecurityEvent.getElementPath();
+ if (elementPath.equals(WSSConstants.SOAP_11_BODY_PATH)) {
+ bodySignedElementSecurityEvent = signedElementSecurityEvent;
+ } else if (elementPath.equals(saml2TokenPath) || elementPath.equals(saml1TokenPath)) {
+ samlTokenSignedElementSecurityEvents.add(signedElementSecurityEvent);
+ }
+ }
+ }
+
+ @Override
+ public XMLSecEvent processNextHeaderEvent(InputProcessorChain inputProcessorChain)
+ throws XMLStreamException, XMLSecurityException {
+ return inputProcessorChain.processHeaderEvent();
+ }
+
+ @Override
+ public XMLSecEvent processNextEvent(InputProcessorChain inputProcessorChain)
+ throws XMLStreamException, XMLSecurityException {
+
+ XMLSecEvent xmlSecEvent = inputProcessorChain.processEvent();
+ if (xmlSecEvent.getEventType() == XMLStreamConstants.START_ELEMENT) {
+ XMLSecStartElement xmlSecStartElement = xmlSecEvent.asStartElement();
+ List<QName> elementPath = xmlSecStartElement.getElementPath();
+ if (elementPath.size() == 3 && WSSUtils.isInSOAPBody(elementPath)) {
+ inputProcessorChain.removeProcessor(this);
+ checkPossessionOfKey(inputProcessorChain, samlAssertionWrapper, subjectSecurityToken);
+ }
+ }
+ return xmlSecEvent;
+ }
+
+ private void checkPossessionOfKey(
+ InputProcessorChain inputProcessorChain, SamlAssertionWrapper samlAssertionWrapper,
+ SecurityToken subjectSecurityToken) throws WSSecurityException {
+
+ try {
+ SecurityToken httpsSecurityToken = getHttpsSecurityToken(inputProcessorChain);
+
+ List<SecurityTokenProvider> securityTokenProviders =
+ inputProcessorChain.getSecurityContext().getRegisteredSecurityTokenProviders();
+
+ List<String> confirmationMethods = samlAssertionWrapper.getConfirmationMethods();
+ for (int i = 0; i < confirmationMethods.size(); i++) {
+ String confirmationMethod = confirmationMethods.get(i);
+ if (OpenSAMLUtil.isMethodHolderOfKey(confirmationMethod)) {
+
+ X509Certificate[] subjectCertificates = subjectSecurityToken.getX509Certificates();
+ PublicKey subjectPublicKey = subjectSecurityToken.getPublicKey();
+ Key subjectSecretKey = null;
+ Map<String, Key> subjectKeyMap = subjectSecurityToken.getSecretKey();
+ if (subjectKeyMap.size() > 0) {
+ subjectSecretKey = subjectKeyMap.values().toArray(new Key[subjectKeyMap.size()])[0];
+ }
+
+ /**
+ * Check the holder-of-key requirements against the received assertion. The subject
+ * credential of the SAML Assertion must have been used to sign some portion of
+ * the message, thus showing proof-of-possession of the private/secret key. Alternatively,
+ * the subject credential of the SAML Assertion must match a client certificate credential
+ * when 2-way TLS is used.
+ */
+
+ //compare https token first:
+ if (httpsSecurityToken != null
+ && httpsSecurityToken.getX509Certificates() != null
+ && httpsSecurityToken.getX509Certificates().length > 0) {
+
+ X509Certificate httpsCertificate = httpsSecurityToken.getX509Certificates()[0];
+
+ //compare certificates:
+ if (subjectCertificates != null && subjectCertificates.length > 0
+ && httpsCertificate.equals(subjectCertificates[0])) {
+ return;
+ //compare public keys:
+ } else if (httpsCertificate.getPublicKey().equals(subjectPublicKey)) {
+ return;
+ }
+ } else {
+ for (int j = 0; j < securityTokenProviders.size(); j++) {
+ SecurityTokenProvider securityTokenProvider = securityTokenProviders.get(j);
+ SecurityToken securityToken = securityTokenProvider.getSecurityToken();
+ if (securityToken == httpsSecurityToken) {
+ continue;
+ }
+ X509Certificate[] x509Certificates = securityToken.getX509Certificates();
+ PublicKey publicKey = securityToken.getPublicKey();
+ Map<String, Key> keyMap = securityToken.getSecretKey();
+ if (x509Certificates != null && x509Certificates.length > 0
+ && subjectCertificates != null && subjectCertificates.length > 0 &&
+ subjectCertificates[0].equals(x509Certificates[0])) {
+ return;
+ }
+ if (publicKey != null && publicKey.equals(subjectPublicKey)) {
+ return;
+ }
+ Iterator<Map.Entry<String,Key>> iterator = keyMap.entrySet().iterator();
+ while(iterator.hasNext()){
+ Map.Entry<String,Key> next = iterator.next();
+ if (next.getValue().equals(subjectSecretKey)) {
+ return;
+ }
+ }
+ }
+ }
+ }
+ else if (OpenSAMLUtil.isMethodSenderVouches(confirmationMethod)) {
+ /**
+ * Check the sender-vouches requirements against the received assertion. The SAML
+ * Assertion and the SOAP Body must be signed by the same signature.
+ */
+
+ //
+ // If we have a 2-way TLS connection, then we don't have to check that the
+ // assertion + SOAP body are signed
+ if (httpsSecurityToken != null
+ && httpsSecurityToken.getX509Certificates() != null
+ && httpsSecurityToken.getX509Certificates().length > 0) {
+ return;
+ }
+
+ SignedElementSecurityEvent samlTokenSignedElementSecurityEvent = null;
+ for (int j = 0; j < samlTokenSignedElementSecurityEvents.size(); j++) {
+ SignedElementSecurityEvent signedElementSecurityEvent = samlTokenSignedElementSecurityEvents.get(j);
+ if (((SecurityToken)securityTokenProvider.getSecurityToken()).getXMLSecEvent() ==
+ signedElementSecurityEvent.getXmlSecEvent()) {
+
+ samlTokenSignedElementSecurityEvent = signedElementSecurityEvent;
+ }
+ }
+ if (bodySignedElementSecurityEvent != null &&
+ samlTokenSignedElementSecurityEvent != null &&
+ bodySignedElementSecurityEvent.getSecurityToken() ==
+ samlTokenSignedElementSecurityEvent.getSecurityToken()) {
+ return;
+ }
+ }
+ }
+ } catch (XMLSecurityException e) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
+ }
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION,
+ "empty", "SAML proof-of-possession of the private/secret key failed");
+ }
+
+ private SecurityToken getHttpsSecurityToken(InputProcessorChain inputProcessorChain) throws XMLSecurityException {
+ List<SecurityTokenProvider> securityTokenProviders =
+ inputProcessorChain.getSecurityContext().getRegisteredSecurityTokenProviders();
+ for (int i = 0; i < securityTokenProviders.size(); i++) {
+ SecurityTokenProvider securityTokenProvider = securityTokenProviders.get(i);
+ SecurityToken securityToken = securityTokenProvider.getSecurityToken();
+ if (securityToken.getTokenType() == WSSConstants.HttpsToken) {
+ return securityToken;
+ }
+ }
+ return null;
+ }
+ }
}
Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java Sat Dec 8 17:41:50 2012
@@ -32,6 +32,7 @@ import org.apache.xml.security.binding.x
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.ext.*;
import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
import org.apache.xml.security.stax.impl.processor.input.AbstractSignatureReferenceVerifyInputProcessor;
import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent;
import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
@@ -180,14 +181,14 @@ public class WSSSignatureReferenceVerify
@Override
protected InternalSignatureReferenceVerifier getSignatureReferenceVerifier(
XMLSecurityProperties securityProperties, InputProcessorChain inputProcessorChain,
- ReferenceType referenceType, QName startElement) throws XMLSecurityException {
+ ReferenceType referenceType, XMLSecStartElement startElement) throws XMLSecurityException {
return new InternalSignatureReferenceVerifier((WSSSecurityProperties) securityProperties,
- inputProcessorChain, referenceType,
- startElement);
+ inputProcessorChain, referenceType, startElement);
}
private void detectReplayAttack(InputProcessorChain inputProcessorChain) throws WSSecurityException {
- TimestampSecurityEvent timestampSecurityEvent = inputProcessorChain.getSecurityContext().get(WSSConstants.PROP_TIMESTAMP_SECURITYEVENT);
+ TimestampSecurityEvent timestampSecurityEvent =
+ inputProcessorChain.getSecurityContext().get(WSSConstants.PROP_TIMESTAMP_SECURITYEVENT);
if (timestampSecurityEvent != null) {
final String cacheKey = String.valueOf(
timestampSecurityEvent.getCreated().getTimeInMillis()) +
@@ -285,7 +286,8 @@ public class WSSSignatureReferenceVerify
SecurityTokenReference securityTokenReference = (SecurityTokenReference) securityToken;
//todo analyse and fix me: the following statement could be problematic
inputProcessorChain.getDocumentContext().setIsInSignedContent(inputProcessorChain.getProcessors().indexOf(internalSignatureReferenceVerifier), internalSignatureReferenceVerifier);
- internalSignatureReferenceVerifier.setStartElement(securityTokenReference.getXmlSecEvents().getLast().asStartElement().getName());
+ XMLSecStartElement xmlSecStartElement = securityTokenReference.getXmlSecEvents().getLast().asStartElement();
+ internalSignatureReferenceVerifier.setStartElement(xmlSecStartElement);
Iterator<XMLSecEvent> xmlSecEventIterator = securityTokenReference.getXmlSecEvents().descendingIterator();
try {
while (xmlSecEventIterator.hasNext()) {
@@ -301,8 +303,8 @@ public class WSSSignatureReferenceVerify
class InternalSignatureReferenceVerifier extends AbstractSignatureReferenceVerifyInputProcessor.InternalSignatureReferenceVerifier {
InternalSignatureReferenceVerifier(WSSSecurityProperties securityProperties, InputProcessorChain inputProcessorChain,
- ReferenceType referenceType, QName startElementName) throws XMLSecurityException {
- super(securityProperties, inputProcessorChain, referenceType, startElementName);
+ ReferenceType referenceType, XMLSecStartElement startElement) throws XMLSecurityException {
+ super(securityProperties, inputProcessorChain, referenceType, startElement);
this.addAfterProcessor(WSSSignatureReferenceVerifyInputProcessor.class.getName());
}
Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java Sat Dec 8 17:41:50 2012
@@ -55,25 +55,6 @@ public class SAMLSecurityToken extends A
this.subjectSecurityToken = subjectSecurityToken;
}
- public SAMLSecurityToken(SAMLVersion samlVersion, Key secretKey, PublicKey publicKey,
- X509Certificate[] x509Certificates, String issuer,
- WSSecurityContext wsSecurityContext, Crypto crypto,
- String id, WSSConstants.KeyIdentifierType keyIdentifierType) {
- super(wsSecurityContext, id, keyIdentifierType);
- this.samlVersion = samlVersion;
- this.issuer = issuer;
- this.crypto = crypto;
- if (secretKey != null) {
- setSecretKey("", secretKey);
- }
- if (publicKey != null) {
- setPublicKey(publicKey);
- }
- if (x509Certificates != null) {
- setX509Certificates(x509Certificates);
- }
- }
-
@Override
public boolean isAsymmetric() throws XMLSecurityException {
if (this.subjectSecurityToken != null && this.subjectSecurityToken.isAsymmetric()) {
Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java Sat Dec 8 17:41:50 2012
@@ -36,6 +36,8 @@ import org.apache.ws.security.stax.ext.I
import org.apache.ws.security.stax.ext.OutboundWSSec;
import org.apache.ws.security.stax.ext.WSSConstants;
import org.apache.ws.security.stax.ext.WSSSecurityProperties;
+import org.apache.ws.security.stax.impl.securityToken.HttpsSecurityToken;
+import org.apache.ws.security.stax.securityEvent.HttpsTokenSecurityEvent;
import org.apache.ws.security.stax.test.AbstractTestBase;
import org.apache.ws.security.stax.test.CallbackHandlerImpl;
import org.apache.ws.security.stax.test.utils.SOAPUtil;
@@ -58,6 +60,7 @@ import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
/**
@@ -514,6 +517,64 @@ public class SAMLTokenHOKTest extends Ab
}
@Test
+ public void testSAMLAssertionHOKTransportSecurityInbound() throws Exception {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+ callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
+ callbackHandler.setIssuer("www.example.com");
+ //callbackHandler.setResource("http://resource.org");
+
+ InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+ String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
+ Properties properties = new Properties();
+ properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
+
+ //some test that we can really sure we get what we want from WSS4J
+ NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 2);
+
+ Element messageSig = (Element)nodeList.item(1);
+ messageSig.getParentNode().removeChild(messageSig);
+
+ javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
+ transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
+ }
+
+ //done signature; now test sig-verification:
+ {
+ WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+ securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
+ securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+ InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+
+ HttpsTokenSecurityEvent httpsTokenSecurityEvent = new HttpsTokenSecurityEvent();
+ httpsTokenSecurityEvent.setAuthenticationType(HttpsTokenSecurityEvent.AuthenticationType.HttpsClientCertificateAuthentication);
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("transmitter");
+ HttpsSecurityToken httpsSecurityToken = new HttpsSecurityToken(
+ securityProperties.getSignatureVerificationCrypto().getX509Certificates(cryptoType)[0], null);
+ httpsTokenSecurityEvent.setSecurityToken(httpsSecurityToken);
+
+ List<SecurityEvent> requestSecurityEvents = new ArrayList<SecurityEvent>();
+ requestSecurityEvents.add(httpsTokenSecurityEvent);
+
+ XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(
+ xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())),
+ requestSecurityEvents, null);
+
+ Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
+
+ //header element must still be there
+ NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 1);
+ }
+ }
+
+ @Test
public void testSAML2AuthnOutbound() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java Sat Dec 8 17:41:50 2012
@@ -18,11 +18,14 @@
*/
package org.apache.ws.security.stax.test.saml;
+import org.apache.ws.security.common.crypto.CryptoType;
import org.apache.ws.security.common.saml.builder.SAML1Constants;
import org.apache.ws.security.common.saml.builder.SAML2Constants;
import org.apache.ws.security.dom.handler.WSHandlerConstants;
import org.apache.ws.security.stax.WSSec;
import org.apache.ws.security.stax.ext.*;
+import org.apache.ws.security.stax.impl.securityToken.HttpsSecurityToken;
+import org.apache.ws.security.stax.securityEvent.HttpsTokenSecurityEvent;
import org.apache.ws.security.stax.test.AbstractTestBase;
import org.apache.ws.security.stax.test.CallbackHandlerImpl;
import org.apache.ws.security.stax.test.utils.StAX2DOM;
@@ -43,6 +46,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
/**
@@ -315,6 +319,60 @@ public class SAMLTokenSVTest extends Abs
}
@Test
+ public void testSAMLAssertionSVTransportSecurityInbound() throws Exception {
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ {
+ SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+ callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
+ callbackHandler.setIssuer("www.example.com");
+ callbackHandler.setResource("http://resource.org");
+
+ InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+ String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+ Properties properties = new Properties();
+ properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
+
+ //some test that we can really sure we get what we want from WSS4J
+ NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 0);
+
+ javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
+ transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
+ }
+
+ //done signature; now test sig-verification:
+ {
+ WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+ securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
+ securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+ InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+
+ HttpsTokenSecurityEvent httpsTokenSecurityEvent = new HttpsTokenSecurityEvent();
+ httpsTokenSecurityEvent.setAuthenticationType(HttpsTokenSecurityEvent.AuthenticationType.HttpsClientCertificateAuthentication);
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("transmitter");
+ HttpsSecurityToken httpsSecurityToken = new HttpsSecurityToken(
+ securityProperties.getSignatureVerificationCrypto().getX509Certificates(cryptoType)[0], null);
+ httpsTokenSecurityEvent.setSecurityToken(httpsSecurityToken);
+
+ List<SecurityEvent> requestSecurityEvents = new ArrayList<SecurityEvent>();
+ requestSecurityEvents.add(httpsTokenSecurityEvent);
+
+ XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(
+ xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())),
+ requestSecurityEvents, null);
+
+ Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
+
+ //header element must still be there
+ NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+ Assert.assertEquals(nodeList.getLength(), 0);
+ }
+ }
+
+ @Test
public void testSAML2AuthnAssertionOutbound() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java Sat Dec 8 17:41:50 2012
@@ -103,14 +103,15 @@ public class SAMLTokenTest extends Abstr
callbackHandler.setIssuer("www.example.com");
InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
- String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+ String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
Properties properties = new Properties();
properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
//some test that we can really sure we get what we want from WSS4J
NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -128,7 +129,7 @@ public class SAMLTokenTest extends Abstr
//header element must still be there
NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
}
}
@@ -174,14 +175,15 @@ public class SAMLTokenTest extends Abstr
callbackHandler.setIssuer("www.example.com");
InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
- String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+ String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
Properties properties = new Properties();
properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
//some test that we can really sure we get what we want from WSS4J
NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -199,7 +201,7 @@ public class SAMLTokenTest extends Abstr
//header element must still be there
NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
}
}
@@ -247,14 +249,15 @@ public class SAMLTokenTest extends Abstr
callbackHandler.setResource("http://resource.org");
InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
- String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+ String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
Properties properties = new Properties();
properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
//some test that we can really sure we get what we want from WSS4J
NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -272,7 +275,7 @@ public class SAMLTokenTest extends Abstr
//header element must still be there
NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
}
}
@@ -319,14 +322,15 @@ public class SAMLTokenTest extends Abstr
callbackHandler.setIssuer("www.example.com");
InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
- String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+ String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
Properties properties = new Properties();
properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
//some test that we can really sure we get what we want from WSS4J
NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -344,7 +348,7 @@ public class SAMLTokenTest extends Abstr
//header element must still be there
NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
}
}
@@ -391,14 +395,15 @@ public class SAMLTokenTest extends Abstr
callbackHandler.setIssuer("www.example.com");
InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
- String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+ String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
Properties properties = new Properties();
properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
//some test that we can really sure we get what we want from WSS4J
NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -416,7 +421,7 @@ public class SAMLTokenTest extends Abstr
//header element must still be there
NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
}
}
@@ -465,14 +470,15 @@ public class SAMLTokenTest extends Abstr
callbackHandler.setResource("http://resource.org");
InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
- String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+ String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
Properties properties = new Properties();
properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+ properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
//some test that we can really sure we get what we want from WSS4J
NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -490,7 +496,7 @@ public class SAMLTokenTest extends Abstr
//header element must still be there
NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
- Assert.assertEquals(nodeList.getLength(), 0);
+ Assert.assertEquals(nodeList.getLength(), 1);
}
}