You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2011/07/22 00:32:13 UTC
svn commit: r1149391 - in /cxf/trunk/systests/rs-security/src/test:
java/org/apache/cxf/systest/jaxrs/security/saml/
java/org/apache/cxf/systest/jaxrs/security/xml/
resources/org/apache/cxf/systest/jaxrs/security/
resources/org/apache/cxf/systest/jaxrs...
Author: sergeyb
Date: Thu Jul 21 22:32:11 2011
New Revision: 1149391
URL: http://svn.apache.org/viewvc?rev=1149391&view=rev
Log:
[CXF-3661] Prototyping XML Encryption handlers in systests - refactoring to follow
Added:
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
- copied, changed from r1148954, cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java (with props)
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java (with props)
cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties (with props)
cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks (with props)
Removed:
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java
Modified:
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java
cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/AbstractSamlInHandler.java Thu Jul 21 22:32:11 2011
@@ -65,6 +65,10 @@ public abstract class AbstractSamlInHand
private static final Logger LOG =
LogUtils.getL7dLogger(AbstractSamlInHandler.class);
+ static {
+ WSSConfig.init();
+ }
+
private Validator samlValidator = new SamlAssertionValidator();
public void setValidator(Validator validator) {
@@ -84,7 +88,7 @@ public abstract class AbstractSamlInHand
AssertionWrapper assertion = new AssertionWrapper(doc.getDocumentElement());
if (assertion.isSigned()) {
RequestData data = new RequestData();
- WSSConfig cfg = new WSSConfig();
+ WSSConfig cfg = WSSConfig.getNewInstance();
data.setWssConfig(cfg);
data.setCallbackHandler(getCallbackHandler(message));
try {
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/BookServerXmlSec.java Thu Jul 21 22:32:11 2011
@@ -19,20 +19,14 @@
package org.apache.cxf.systest.jaxrs.security.xml;
-import java.util.HashMap;
-import java.util.Map;
-
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.SpringBusFactory;
-import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
-import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
-import org.apache.cxf.systest.jaxrs.security.BookStore;
import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
import org.apache.cxf.testutil.common.TestUtil;
public class BookServerXmlSec extends AbstractBusTestServerBase {
- public static final String PORT = TestUtil.getPortNumber("jaxrs-xmlsig");
+ public static final String PORT = TestUtil.getPortNumber("jaxrs-xmlsec");
private static final String SERVER_CONFIG_FILE =
"org/apache/cxf/systest/jaxrs/security/xml/server.xml";
@@ -40,25 +34,13 @@ public class BookServerXmlSec extends Ab
SpringBusFactory bf = new SpringBusFactory();
Bus springBus = bf.createBus(SERVER_CONFIG_FILE);
BusFactory.setDefaultBus(springBus);
+ setBus(springBus);
- JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
-
- sf.setResourceClasses(BookStore.class);
-
- sf.setProvider(new XmlSigInHandler());
-
- sf.setResourceProvider(BookStore.class,
- new SingletonResourceProvider(new BookStore(), true));
- sf.setAddress("https://localhost:" + PORT + "/");
-
- Map<String, Object> properties = new HashMap<String, Object>();
- properties.put("ws-security.callback-handler",
- "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
- properties.put("ws-security.signature.properties",
- "org/apache/cxf/systest/jaxrs/security/alice.properties");
- sf.setProperties(properties);
-
- sf.create();
+ try {
+ new BookServerXmlSec();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
public static void main(String[] args) {
Copied: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java (from r1148954, cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java?p2=cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java&p1=cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java&r1=1148954&r2=1149391&rev=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSigTest.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java Thu Jul 21 22:32:11 2011
@@ -35,7 +35,7 @@ import org.apache.cxf.testutil.common.Ab
import org.junit.BeforeClass;
import org.junit.Test;
-public class JAXRSXmlSigTest extends AbstractBusClientServerTestBase {
+public class JAXRSXmlSecTest extends AbstractBusClientServerTestBase {
public static final String PORT = BookServerXmlSec.PORT;
@BeforeClass
@@ -46,12 +46,12 @@ public class JAXRSXmlSigTest extends Abs
@Test
public void testPostBookWithEnvelopedSig() throws Exception {
- String address = "https://localhost:" + PORT + "/bookstore/books";
+ String address = "https://localhost:" + PORT + "/xmlsig/bookstore/books";
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setAddress(address);
SpringBusFactory bf = new SpringBusFactory();
- URL busFile = JAXRSXmlSigTest.class.getResource("client.xml");
+ URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
Bus springBus = bf.createBus(busFile.toString());
bean.setBus(springBus);
@@ -81,5 +81,83 @@ public class JAXRSXmlSigTest extends Abs
}
+ @Test
+ public void testPostEncryptedBook() throws Exception {
+ String address = "https://localhost:" + PORT + "/xmlenc/bookstore/books";
+ JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+ bean.setAddress(address);
+
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
+ Bus springBus = bf.createBus(busFile.toString());
+ bean.setBus(springBus);
+
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put("ws-security.callback-handler",
+ "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+ properties.put("ws-security.encryption.username", "bob");
+ properties.put("ws-security.encryption.properties",
+ "org/apache/cxf/systest/jaxrs/security/bob.properties");
+ bean.setProperties(properties);
+ bean.getOutInterceptors().add(new XmlEncOutInterceptor());
+
+
+ WebClient wc = bean.createWebClient();
+ try {
+ Book book = wc.post(new Book("CXF", 126L), Book.class);
+ assertEquals(126L, book.getId());
+ } catch (ServerWebApplicationException ex) {
+ fail(ex.getMessage());
+ } catch (ClientWebApplicationException ex) {
+ if (ex.getCause() != null && ex.getCause().getMessage() != null) {
+ fail(ex.getCause().getMessage());
+ } else {
+ fail(ex.getMessage());
+ }
+ }
+
+ }
+
+ @Test
+ public void testPostEncryptedSignedBook() throws Exception {
+ String address = "https://localhost:" + PORT + "/xmlsec/bookstore/books";
+ JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+ bean.setAddress(address);
+
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
+ Bus springBus = bf.createBus(busFile.toString());
+ bean.setBus(springBus);
+
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put("ws-security.callback-handler",
+ "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+ properties.put("ws-security.encryption.username", "bob");
+ properties.put("ws-security.encryption.properties",
+ "org/apache/cxf/systest/jaxrs/security/bob.properties");
+ properties.put("ws-security.signature.username", "alice");
+ properties.put("ws-security.signature.properties",
+ "org/apache/cxf/systest/jaxrs/security/alice.properties");
+ bean.setProperties(properties);
+ bean.getOutInterceptors().add(new XmlSigOutInterceptor());
+ bean.getOutInterceptors().add(new XmlEncOutInterceptor());
+
+
+ WebClient wc = bean.createWebClient();
+ try {
+ Book book = wc.post(new Book("CXF", 126L), Book.class);
+ assertEquals(126L, book.getId());
+ } catch (ServerWebApplicationException ex) {
+ fail(ex.getMessage());
+ } catch (ClientWebApplicationException ex) {
+ if (ex.getCause() != null && ex.getCause().getMessage() != null) {
+ fail(ex.getCause().getMessage());
+ } else {
+ fail(ex.getMessage());
+ }
+ }
+
+ }
+
}
Added: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java?rev=1149391&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java (added)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java Thu Jul 21 22:32:11 2011
@@ -0,0 +1,339 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systest.jaxrs.security.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.security.auth.callback.CallbackHandler;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.xml.stream.XMLStreamReader;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxrs.ext.RequestHandler;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.staxutils.W3CDOMStreamReader;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.ws.security.validate.Credential;
+import org.apache.ws.security.validate.SignatureTrustValidator;
+import org.apache.xml.security.utils.Constants;
+
+public class XmlEncInHandler implements RequestHandler {
+ private static final Logger LOG =
+ LogUtils.getL7dLogger(XmlEncInHandler.class);
+
+ static {
+ WSSConfig.init();
+ }
+
+ public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
+
+ String method = (String)message.get(Message.HTTP_REQUEST_METHOD);
+ if ("GET".equals(method)) {
+ return null;
+ }
+
+ InputStream is = message.getContent(InputStream.class);
+ Document doc = null;
+ try {
+ doc = DOMUtils.readXml(is);
+ } catch (Exception ex) {
+ throwFault("Invalid XML payload", ex);
+ }
+
+
+ Element root = doc.getDocumentElement();
+ Element encKeyElement = getNode(root, WSConstants.ENC_NS, "EncryptedKey", 0);
+ if (encKeyElement == null) {
+ throwFault("EncryptedKey element is not available", null);
+ }
+ byte[] symmetricKeyBytes = getSymmetricKey(message, encKeyElement);
+
+ String algorithm = getEncodingMethodAlgorithm(root);
+ Element cipherValue = getNode(root, WSConstants.ENC_NS, "CipherValue", 1);
+ if (cipherValue == null) {
+ throwFault("CipherValue element is not available", null);
+ }
+
+ byte[] decrypedPayload = null;
+ try {
+ decrypedPayload = decryptPayload(symmetricKeyBytes, cipherValue.getTextContent().trim(),
+ algorithm);
+ } catch (Exception ex) {
+ throwFault("Payload can not be decrypted", ex);
+ }
+
+ Document payloadDoc = null;
+ try {
+ payloadDoc = DOMUtils.readXml(new InputStreamReader(new ByteArrayInputStream(decrypedPayload),
+ "UTF-8"));
+ } catch (Exception ex) {
+ throwFault("Payload document can not be created", ex);
+ }
+ message.setContent(XMLStreamReader.class,
+ new W3CDOMStreamReader(payloadDoc));
+ message.setContent(InputStream.class, null);
+ return null;
+ }
+
+ private byte[] getSymmetricKey(Message message, Element encKeyElement) {
+ Element certNode = getNode(encKeyElement,
+ Constants.SignatureSpecNS, "X509Certificate", 0);
+ if (certNode == null) {
+ throwFault("Certificate is missing", null);
+ }
+ byte[] certBytes = null;
+ try {
+ certBytes = Base64Utility.decode(certNode.getTextContent().trim());
+ } catch (Base64Exception ex) {
+ throwFault("Base64 decoding has failed", ex);
+ }
+
+ X509Certificate cert = null;
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(certBytes));
+ } catch (Exception ex) {
+ throwFault("X509Certificate can not be created", ex);
+ }
+
+ Crypto crypto = null;
+ try {
+ crypto = getCrypto(message, SecurityConstants.ENCRYPT_PROPERTIES);
+ } catch (Exception ex) {
+ throwFault("Crypto can not be loaded", ex);
+ }
+
+
+ Credential trustCredential = new Credential();
+ trustCredential.setPublicKey(null);
+ trustCredential.setCertificates(new X509Certificate[]{cert});
+ try {
+ validateTrust(trustCredential, crypto);
+ } catch (Exception ex) {
+ throwFault(ex.getMessage(), ex);
+ }
+
+ // now start decrypting
+ String algorithm = getEncodingMethodAlgorithm(encKeyElement);
+ Element cipherValue = getNode(encKeyElement, WSConstants.ENC_NS,
+ "CipherValue", 0);
+ if (cipherValue == null) {
+ throwFault("CipherValue element is not available", null);
+ }
+ try {
+ return decryptSymmetricKey(cipherValue.getTextContent().trim(),
+ cert,
+ crypto,
+ algorithm,
+ message);
+ } catch (Exception ex) {
+ throwFault(ex.getMessage(), ex);
+ }
+ return null;
+ }
+
+ private String getEncodingMethodAlgorithm(Element parent) {
+ Element encMethod = getNode(parent, WSConstants.ENC_NS, "EncryptionMethod", 0);
+ if (encMethod == null) {
+ throwFault("EncryptionMethod element is not available", null);
+ }
+ return encMethod.getAttribute("Algorithm");
+ }
+
+ protected byte[] decryptSymmetricKey(String base64EncodedKey,
+ X509Certificate cert,
+ Crypto crypto,
+ String keyEncAlgo,
+ Message message) throws WSSecurityException {
+ CallbackHandler callback = getCallbackHandler(message);
+ PrivateKey key = null;
+ try {
+ key = crypto.getPrivateKey(cert, callback);
+ } catch (Exception ex) {
+ throwFault("Encrypted key can not be decrypted", ex);
+ }
+ Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
+ try {
+ // see more: WSS4J EncryptedDataProcessor
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ } catch (InvalidKeyException e) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_ENCRYPTION, null, null, e
+ );
+ }
+ try {
+ byte[] encryptedBytes = Base64Utility.decode(base64EncodedKey);
+ return doDecrypt(cipher, encryptedBytes);
+ } catch (Base64Exception ex) {
+ throwFault("Base64 decoding has failed", ex);
+ } catch (Exception ex) {
+ throwFault("Encrypted key can not be decrypted", ex);
+ }
+ return null;
+
+ }
+
+ protected byte[] decryptPayload(byte[] secretKeyBytes,
+ String base64EncodedPayload,
+ String symEncAlgo) throws WSSecurityException {
+ byte[] encryptedBytes = null;
+ try {
+ encryptedBytes = Base64Utility.decode(base64EncodedPayload);
+ } catch (Base64Exception ex) {
+ throwFault("Base64 decoding has failed", ex);
+ }
+
+ Cipher cipher = WSSecurityUtil.getCipherInstance(symEncAlgo);
+ try {
+ // see more: WSS4J EncryptedDataProcessor
+ SecretKey key = WSSecurityUtil.prepareSecretKey(symEncAlgo, secretKeyBytes);
+ // IV spec
+ int ivLen = cipher.getBlockSize();
+ byte[] ivBytes = new byte[ivLen];
+ System.arraycopy(encryptedBytes, 0, ivBytes, 0, ivLen);
+ IvParameterSpec iv = new IvParameterSpec(ivBytes);
+
+ cipher.init(Cipher.DECRYPT_MODE, key, iv);
+
+ return cipher.doFinal(encryptedBytes,
+ ivLen,
+ encryptedBytes.length - ivLen);
+
+ } catch (InvalidKeyException e) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_ENCRYPTION, null, null, e
+ );
+ } catch (Exception e) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_ENCRYPTION, null, null, e);
+ }
+ }
+
+ private byte[] doDecrypt(Cipher cipher, byte[] encryptedBytes) throws Exception {
+ return cipher.doFinal(encryptedBytes);
+ }
+
+ private Element getNode(Element parent, String ns, String name, int index) {
+ NodeList list = parent.getElementsByTagNameNS(ns, name);
+ if (list != null && list.getLength() >= index + 1) {
+ return (Element)list.item(index);
+ }
+ return null;
+ }
+
+ private void validateTrust(Credential cred, Crypto crypto) throws Exception {
+ SignatureTrustValidator validator = new SignatureTrustValidator();
+ RequestData data = new RequestData();
+ data.setSigCrypto(crypto);
+ validator.validate(cred, data);
+ }
+
+ protected void throwFault(String error, Exception ex) {
+ // TODO: get bundle resource message once this filter is moved
+ // to rt/rs/security
+ LOG.warning(error);
+ Response response = Response.status(401).entity(error).build();
+ throw ex != null ? new WebApplicationException(ex, response) : new WebApplicationException(response);
+ }
+
+ // this code will be moved to a common utility class
+ protected Crypto getCrypto(Message message, String propKey)
+ throws IOException, WSSecurityException {
+
+ Object o = message.getContextualProperty(propKey);
+ if (o == null) {
+ return null;
+ }
+
+ ClassLoader orig = Thread.currentThread().getContextClassLoader();
+ try {
+ URL url = ClassLoaderUtils.getResource((String)o, this.getClass());
+ if (url == null) {
+ ResourceManager manager = message.getExchange()
+ .getBus().getExtension(ResourceManager.class);
+ ClassLoader loader = manager.resolveResource("", ClassLoader.class);
+ if (loader != null) {
+ Thread.currentThread().setContextClassLoader(loader);
+ }
+ url = manager.resolveResource((String)o, URL.class);
+ }
+ if (url != null) {
+ Properties props = new Properties();
+ InputStream in = url.openStream();
+ props.load(in);
+ in.close();
+ return CryptoFactory.getInstance(props);
+ } else {
+ return CryptoFactory.getInstance((String)o);
+ }
+ } finally {
+ Thread.currentThread().setContextClassLoader(orig);
+ }
+ }
+
+ private CallbackHandler getCallbackHandler(Message message) {
+ //Then try to get the password from the given callback handler
+ Object o = message.getContextualProperty(SecurityConstants.CALLBACK_HANDLER);
+
+ CallbackHandler handler = null;
+ if (o instanceof CallbackHandler) {
+ handler = (CallbackHandler)o;
+ } else if (o instanceof String) {
+ try {
+ handler = (CallbackHandler)ClassLoaderUtils
+ .loadClass((String)o, this.getClass()).newInstance();
+ } catch (Exception e) {
+ handler = null;
+ }
+ }
+ return handler;
+ }
+}
Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncInHandler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java?rev=1149391&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java (added)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java Thu Jul 21 22:32:11 2011
@@ -0,0 +1,501 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs.security.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageContentsList;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.staxutils.W3CDOMStreamWriter;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.components.crypto.CryptoType;
+import org.apache.ws.security.message.token.DOMX509Data;
+import org.apache.ws.security.message.token.DOMX509IssuerSerial;
+import org.apache.ws.security.util.Base64;
+import org.apache.ws.security.util.UUIDGenerator;
+import org.apache.ws.security.util.WSSecurityUtil;
+import org.apache.xml.security.algorithms.JCEMapper;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.encryption.XMLEncryptionException;
+
+public class XmlEncOutInterceptor extends AbstractPhaseInterceptor<Message> {
+ private static final Logger LOG =
+ LogUtils.getL7dLogger(XmlEncOutInterceptor.class);
+ private static final String CRYPTO_CACHE = "ws-security.crypto.cache";
+
+ static {
+ WSSConfig.init();
+ }
+
+ private boolean encryptSymmetricKey = true;
+ private SecretKey symmetricKey;
+ private String keyEncAlgo = XMLCipher.RSA_OAEP;
+ private String symEncAlgo = XMLCipher.AES_256;
+
+ public XmlEncOutInterceptor() {
+ super(Phase.WRITE);
+ addAfter(XmlSigOutInterceptor.class.getName());
+ }
+
+ public void handleMessage(Message message) throws Fault {
+ try {
+ Object body = getRequestBody(message);
+ if (body == null) {
+ return;
+ }
+ Document doc = getDomDocument(body, message);
+ if (doc == null) {
+ return;
+ }
+
+ Document encryptedDataDoc = encryptDocument(message, doc);
+ message.setContent(List.class,
+ new MessageContentsList(new DOMSource(encryptedDataDoc)));
+ } catch (Exception ex) {
+ StringWriter sw = new StringWriter();
+ ex.printStackTrace(new PrintWriter(sw));
+ LOG.warning(sw.toString());
+ throw new Fault(new RuntimeException(ex.getMessage() + ", stacktrace: " + sw.toString()));
+ }
+ }
+
+ // at the moment all the doc gets encrypted
+ private Document encryptDocument(Message message, Document payloadDoc)
+ throws Exception {
+
+ byte[] secretKey = getSymmetricKey();
+
+ Document encryptedDataDoc = DOMUtils.createDocument();
+ Element encryptedDataElement = createEncryptedDataElement(encryptedDataDoc);
+ if (encryptSymmetricKey) {
+ Crypto crypto = getCrypto(message,
+ SecurityConstants.ENCRYPT_CRYPTO,
+ SecurityConstants.ENCRYPT_PROPERTIES);
+
+ String user = getUserName(message, crypto);
+ if (StringUtils.isEmpty(user)) {
+ return null;
+ }
+ X509Certificate cert = getReceiverCertificate(crypto, user);
+ byte[] encryptedSecretKey = encryptSymmetricKey(secretKey, cert, crypto);
+
+ addEncryptedKeyElement(encryptedDataElement, cert, encryptedSecretKey);
+ }
+
+ // encrypt payloadDoc
+ XMLCipher xmlCipher = null;
+ try {
+ xmlCipher = XMLCipher.getInstance(symEncAlgo);
+ } catch (XMLEncryptionException ex) {
+ throw new WSSecurityException(
+ WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, ex
+ );
+ }
+ xmlCipher.init(XMLCipher.ENCRYPT_MODE, symmetricKey);
+ Document result = xmlCipher.doFinal(payloadDoc, payloadDoc.getDocumentElement(), false);
+ NodeList list = result.getElementsByTagNameNS(WSConstants.ENC_NS, "CipherValue");
+ if (list.getLength() != 1) {
+ throw new WSSecurityException("Payload CipherData is missing", null);
+ }
+ String cipherText = ((Element)list.item(0)).getTextContent().trim();
+ Element cipherValue =
+ createCipherValue(encryptedDataDoc, encryptedDataDoc.getDocumentElement());
+ cipherValue.appendChild(encryptedDataDoc.createTextNode(cipherText));
+
+ //StaxUtils.copy(new DOMSource(encryptedDataDoc), System.out);
+ return encryptedDataDoc;
+ }
+
+ private byte[] getSymmetricKey() throws Exception {
+ synchronized (this) {
+ if (symmetricKey == null) {
+ KeyGenerator keyGen = getKeyGenerator();
+ symmetricKey = keyGen.generateKey();
+ }
+ }
+ return symmetricKey.getEncoded();
+ }
+
+ private X509Certificate getReceiverCertificate(Crypto crypto, String user) throws Exception {
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias(user);
+ X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+ if (certs == null || certs.length <= 0) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILURE,
+ "noUserCertsFound",
+ new Object[] {user, "encryption"}
+ );
+ }
+ return certs[0];
+ }
+
+ private KeyGenerator getKeyGenerator() throws WSSecurityException {
+ try {
+ //
+ // Assume AES as default, so initialize it
+ //
+ String keyAlgorithm = JCEMapper.getJCEKeyAlgorithmFromURI(symEncAlgo);
+ KeyGenerator keyGen = KeyGenerator.getInstance(keyAlgorithm);
+ if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_128)) {
+ keyGen.init(128);
+ } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_192)) {
+ keyGen.init(192);
+ } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_256)) {
+ keyGen.init(256);
+ }
+ return keyGen;
+ } catch (NoSuchAlgorithmException e) {
+ throw new WSSecurityException(
+ WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e
+ );
+ }
+ }
+
+ // Apache Security XMLCipher does not support
+ // Certificates for encrypting the keys
+ protected byte[] encryptSymmetricKey(byte[] keyBytes,
+ X509Certificate remoteCert,
+ Crypto crypto) throws WSSecurityException {
+ Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
+ try {
+ cipher.init(Cipher.ENCRYPT_MODE, remoteCert);
+ } catch (InvalidKeyException e) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_ENCRYPTION, null, null, e
+ );
+ }
+ int blockSize = cipher.getBlockSize();
+ if (blockSize > 0 && blockSize < keyBytes.length) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILURE,
+ "unsupportedKeyTransp",
+ new Object[] {"public key algorithm too weak to encrypt symmetric key"}
+ );
+ }
+ byte[] encryptedEphemeralKey = null;
+ try {
+ encryptedEphemeralKey = cipher.doFinal(keyBytes);
+ } catch (IllegalStateException ex) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_ENCRYPTION, null, null, ex
+ );
+ } catch (IllegalBlockSizeException ex) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_ENCRYPTION, null, null, ex
+ );
+ } catch (BadPaddingException ex) {
+ throw new WSSecurityException(
+ WSSecurityException.FAILED_ENCRYPTION, null, null, ex
+ );
+ }
+
+ return encryptedEphemeralKey;
+
+ }
+
+ private void addEncryptedKeyElement(Element encryptedDataElement,
+ X509Certificate cert,
+ byte[] encryptedKey) throws Exception {
+
+ Document doc = encryptedDataElement.getOwnerDocument();
+
+ String encodedKey = Base64Utility.encode(encryptedKey);
+ Element encryptedKeyElement = createEncryptedKeyElement(doc);
+ String encKeyId = "EK-" + UUIDGenerator.getUUID();
+ encryptedKeyElement.setAttributeNS(null, "Id", encKeyId);
+
+ Element keyInfoElement = createKeyInfoElement(doc, cert, WSConstants.X509_KEY_IDENTIFIER);
+ encryptedKeyElement.appendChild(keyInfoElement);
+
+ Element xencCipherValue = createCipherValue(doc, encryptedKeyElement);
+ xencCipherValue.appendChild(doc.createTextNode(encodedKey));
+
+
+ encryptedDataElement.appendChild(encryptedKeyElement);
+ }
+
+ protected Element createCipherValue(Document doc, Element encryptedKey) {
+ Element cipherData =
+ doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherData");
+ Element cipherValue =
+ doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherValue");
+ cipherData.appendChild(cipherValue);
+ encryptedKey.appendChild(cipherData);
+ return cipherValue;
+ }
+
+ private Element createKeyInfoElement(Document encryptedDataDoc,
+ X509Certificate remoteCert,
+ int keyIdentifierType) throws Exception {
+ Element keyInfoElement =
+ encryptedDataDoc.createElementNS(
+ WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
+ );
+
+ Node keyIdentifierNode = null;
+ switch (keyIdentifierType) {
+ case WSConstants.X509_KEY_IDENTIFIER:
+ byte data[] = null;
+ try {
+ data = remoteCert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ throw new WSSecurityException(
+ WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, "encodeError", null, e
+ );
+ }
+ Text text = encryptedDataDoc.createTextNode(Base64.encode(data));
+ Element cert = encryptedDataDoc.createElementNS(
+ WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.X509_CERT_LN);
+ cert.appendChild(text);
+ Element x509Data = encryptedDataDoc.createElementNS(
+ WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.X509_DATA_LN);
+
+ x509Data.appendChild(cert);
+ keyIdentifierNode = x509Data;
+ break;
+
+ case WSConstants.ISSUER_SERIAL:
+ String issuer = remoteCert.getIssuerDN().getName();
+ java.math.BigInteger serialNumber = remoteCert.getSerialNumber();
+ DOMX509IssuerSerial domIssuerSerial =
+ new DOMX509IssuerSerial(
+ encryptedDataDoc, issuer, serialNumber
+ );
+ DOMX509Data domX509Data = new DOMX509Data(encryptedDataDoc, domIssuerSerial);
+ keyIdentifierNode = domX509Data.getElement();
+ break;
+ default:
+ throw new WSSecurityException("Unsupported key identifier:" + keyIdentifierType);
+ }
+
+ keyInfoElement.appendChild(keyIdentifierNode);
+
+ return keyInfoElement;
+ }
+
+ protected Element createEncryptedKeyElement(Document encryptedDataDoc) {
+ Element encryptedKey =
+ encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptedKey");
+
+ Element encryptionMethod =
+ encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX
+ + ":EncryptionMethod");
+ encryptionMethod.setAttributeNS(null, "Algorithm", keyEncAlgo);
+ encryptedKey.appendChild(encryptionMethod);
+ return encryptedKey;
+ }
+
+ protected Element createEncryptedDataElement(Document encryptedDataDoc) {
+ Element encryptedData =
+ encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptedData");
+
+ WSSecurityUtil.setNamespace(encryptedData, WSConstants.ENC_NS, WSConstants.ENC_PREFIX);
+
+ Element encryptionMethod =
+ encryptedDataDoc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX
+ + ":EncryptionMethod");
+ encryptionMethod.setAttributeNS(null, "Algorithm", symEncAlgo);
+ encryptedData.appendChild(encryptionMethod);
+ encryptedDataDoc.appendChild(encryptedData);
+
+ return encryptedData;
+ }
+
+
+ private Object getRequestBody(Message message) {
+ MessageContentsList objs = MessageContentsList.getContentsList(message);
+ if (objs == null || objs.size() == 0) {
+ return null;
+ } else {
+ return objs.get(0);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Document getDomDocument(Object body, Message m) throws Exception {
+
+ if (body instanceof Document) {
+ return (Document)body;
+ }
+ if (body instanceof DOMSource) {
+ return (Document)((DOMSource)body).getNode();
+ }
+
+ ProviderFactory pf = ProviderFactory.getInstance(m);
+
+ Object providerObject = pf.createMessageBodyWriter(body.getClass(),
+ body.getClass(), new Annotation[]{},
+ MediaType.APPLICATION_XML_TYPE, m);
+ if (!(providerObject instanceof JAXBElementProvider)) {
+ return null;
+ }
+ JAXBElementProvider provider = (JAXBElementProvider)providerObject;
+ W3CDOMStreamWriter writer = new W3CDOMStreamWriter();
+ m.setContent(XMLStreamWriter.class, writer);
+ provider.writeTo(body, body.getClass(),
+ body.getClass(), new Annotation[]{},
+ MediaType.APPLICATION_XML_TYPE,
+ (MultivaluedMap)m.get(Message.PROTOCOL_HEADERS), null);
+ return writer.getDocument();
+ }
+
+ // This code will be moved to a common utility class
+ private String getUserName(Message message, Crypto crypto) {
+ String userNameKey = SecurityConstants.ENCRYPT_USERNAME;
+ String user = (String)message.getContextualProperty(userNameKey);
+ if (crypto != null && StringUtils.isEmpty(user)) {
+ try {
+ user = crypto.getDefaultX509Identifier();
+ } catch (WSSecurityException e1) {
+ throw new Fault(e1);
+ }
+ }
+ return user;
+ }
+
+
+ private Crypto getCrypto(Message message,
+ String cryptoKey,
+ String propKey) {
+ Crypto crypto = (Crypto)message.getContextualProperty(cryptoKey);
+ if (crypto != null) {
+ return crypto;
+ }
+
+ Object o = message.getContextualProperty(propKey);
+ if (o == null) {
+ return null;
+ }
+
+ crypto = getCryptoCache(message).get(o);
+ if (crypto != null) {
+ return crypto;
+ }
+ Properties properties = null;
+ if (o instanceof Properties) {
+ properties = (Properties)o;
+ } else if (o instanceof String) {
+ ResourceManager rm = message.getExchange().get(Bus.class).getExtension(ResourceManager.class);
+ URL url = rm.resolveResource((String)o, URL.class);
+ try {
+ if (url == null) {
+ url = ClassLoaderUtils.getResource((String)o, this.getClass());
+ }
+ if (url == null) {
+ try {
+ url = new URL((String)o);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ if (url != null) {
+ InputStream ins = url.openStream();
+ properties = new Properties();
+ properties.load(ins);
+ ins.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (o instanceof URL) {
+ properties = new Properties();
+ try {
+ InputStream ins = ((URL)o).openStream();
+ properties.load(ins);
+ ins.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ if (properties != null) {
+ try {
+ crypto = CryptoFactory.getInstance(properties);
+ } catch (Exception ex) {
+ return null;
+ }
+ getCryptoCache(message).put(o, crypto);
+ }
+ return crypto;
+ }
+
+ protected final Map<Object, Crypto> getCryptoCache(Message message) {
+ EndpointInfo info = message.getExchange().get(Endpoint.class).getEndpointInfo();
+ synchronized (info) {
+ Map<Object, Crypto> o =
+ CastUtils.cast((Map<?, ?>)message.getContextualProperty(CRYPTO_CACHE));
+ if (o == null) {
+ o = new ConcurrentHashMap<Object, Crypto>();
+ info.setProperty(CRYPTO_CACHE, o);
+ }
+ return o;
+ }
+ }
+}
Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlEncOutInterceptor.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigInHandler.java Thu Jul 21 22:32:11 2011
@@ -44,6 +44,7 @@ import org.apache.cxf.message.Message;
import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.staxutils.W3CDOMStreamReader;
import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
@@ -63,7 +64,7 @@ public class XmlSigInHandler implements
LogUtils.getL7dLogger(XmlSigInHandler.class);
static {
- org.apache.xml.security.Init.init();
+ WSSConfig.init();
}
public Response handleRequest(Message message, ClassResourceInfo resourceClass) {
@@ -73,14 +74,23 @@ public class XmlSigInHandler implements
return null;
}
- InputStream is = message.getContent(InputStream.class);
Document doc = null;
- try {
- doc = DOMUtils.readXml(is);
- } catch (Exception ex) {
- throwFault("Invalid XML payload", ex);
+ InputStream is = message.getContent(InputStream.class);
+ if (is != null) {
+ try {
+ doc = DOMUtils.readXml(is);
+ } catch (Exception ex) {
+ throwFault("Invalid XML payload", ex);
+ }
+ } else {
+ XMLStreamReader reader = message.getContent(XMLStreamReader.class);
+ if (reader instanceof W3CDOMStreamReader) {
+ doc = ((W3CDOMStreamReader)reader).getDocument();
+ }
+ }
+ if (doc == null) {
+ throwFault("No payload is available", null);
}
-
Element root = doc.getDocumentElement();
Element sigElement = getSignatureElement(root);
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/XmlSigOutInterceptor.java Thu Jul 21 22:32:11 2011
@@ -59,6 +59,7 @@ import org.apache.cxf.service.model.Endp
import org.apache.cxf.staxutils.W3CDOMStreamWriter;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
@@ -75,7 +76,7 @@ public class XmlSigOutInterceptor extend
private static final String CRYPTO_CACHE = "ws-security.crypto.cache";
static {
- org.apache.xml.security.Init.init();
+ WSSConfig.init();
}
private boolean createReferenceId = true;
@@ -182,6 +183,10 @@ public class XmlSigOutInterceptor extend
@SuppressWarnings("unchecked")
private Document getDomDocument(Object body, Message m) throws Exception {
+ if (body instanceof Document) {
+ return (Document)body;
+ }
+
ProviderFactory pf = ProviderFactory.getInstance(m);
Object providerObject = pf.createMessageBodyWriter(body.getClass(),
Modified: cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml?rev=1149391&r1=1149390&r2=1149391&view=diff
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml (original)
+++ cxf/trunk/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml Thu Jul 21 22:32:11 2011
@@ -23,7 +23,9 @@ under the License.
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:cxf="http://cxf.apache.org/core"
+ xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
+ http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
@@ -40,7 +42,7 @@ under the License.
</cxf:bus>
<httpj:engine-factory id="port-9095-tls-config">
- <httpj:engine port="${testutil.ports.jaxrs-xmlsig}">
+ <httpj:engine port="${testutil.ports.jaxrs-xmlsec}">
<httpj:tlsServerParameters>
<sec:keyManagers keyPassword="password">
<sec:keyStore type="JKS" password="password"
@@ -61,5 +63,61 @@ under the License.
</httpj:tlsServerParameters>
</httpj:engine>
</httpj:engine-factory>
+
+ <bean id="serviceBean" class="org.apache.cxf.systest.jaxrs.security.BookStore"/>
+ <bean id="xmlSigHandler" class="org.apache.cxf.systest.jaxrs.security.xml.XmlSigInHandler"/>
+ <bean id="xmlEncHandler" class="org.apache.cxf.systest.jaxrs.security.xml.XmlEncInHandler"/>
+
+ <jaxrs:server
+ address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlsig">
+ <jaxrs:serviceBeans>
+ <ref bean="serviceBean"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="xmlSigHandler"/>
+ </jaxrs:providers>
+ <jaxrs:properties>
+ <entry key="ws-security.signature.properties"
+ value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>
+ </jaxrs:properties>
+
+ </jaxrs:server>
+
+ <jaxrs:server
+ address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlenc">
+ <jaxrs:serviceBeans>
+ <ref bean="serviceBean"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="xmlEncHandler"/>
+ </jaxrs:providers>
+ <jaxrs:properties>
+ <entry key="ws-security.callback-handler"
+ value="org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback"/>
+ <entry key="ws-security.encryption.properties"
+ value="org/apache/cxf/systest/jaxrs/security/bob.properties"/>
+ </jaxrs:properties>
+
+ </jaxrs:server>
+
+ <jaxrs:server
+ address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlsec">
+ <jaxrs:serviceBeans>
+ <ref bean="serviceBean"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="xmlEncHandler"/>
+ <ref bean="xmlSigHandler"/>
+ </jaxrs:providers>
+ <jaxrs:properties>
+ <entry key="ws-security.callback-handler"
+ value="org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback"/>
+ <entry key="ws-security.encryption.properties"
+ value="org/apache/cxf/systest/jaxrs/security/bob.properties"/>
+ <entry key="ws-security.signature.properties"
+ value="org/apache/cxf/systest/jaxrs/security/alice.properties"/>
+ </jaxrs:properties>
+
+ </jaxrs:server>
</beans>
Added: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties?rev=1149391&view=auto
==============================================================================
--- cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties (added)
+++ cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties Thu Jul 21 22:32:11 2011
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=password
+org.apache.ws.security.crypto.merlin.keystore.alias=bob
+org.apache.ws.security.crypto.merlin.keystore.file=org/apache/cxf/systest/jaxrs/security/certs/bob.jks
Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.properties
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks?rev=1149391&view=auto
==============================================================================
Binary file - no diff available.
Propchange: cxf/trunk/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream