You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2014/10/10 16:59:01 UTC

git commit: [CXF-6042] - Support certificate constraints in JAX-RS XML Signature

Repository: cxf
Updated Branches:
  refs/heads/master 9505bc608 -> fac67a202


[CXF-6042] - Support certificate constraints in JAX-RS XML Signature


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/fac67a20
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/fac67a20
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/fac67a20

Branch: refs/heads/master
Commit: fac67a202f3303b1709ebccef0bc48ddc4838639
Parents: 9505bc6
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Fri Oct 10 15:58:16 2014 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Fri Oct 10 15:58:34 2014 +0100

----------------------------------------------------------------------
 .../cxf/rs/security/common/TrustValidator.java  |   9 +++
 .../security/xml/AbstractXmlSigInHandler.java   |  30 +++++++-
 .../rs/security/xml/XmlSecInInterceptor.java    |  27 ++++++-
 .../jaxrs/security/xml/JAXRSXmlSecTest.java     |  73 +++++++++++++------
 .../cxf/systest/jaxrs/security/xml/server.xml   |  28 ++++++-
 .../systest/jaxrs/security/xml/stax-server.xml  |  27 ++++++-
 .../cxf/systest/jaxrs/security/certs/alice.jks  | Bin 1861 -> 2428 bytes
 .../cxf/systest/jaxrs/security/certs/bob.jks    | Bin 1820 -> 2422 bytes
 8 files changed, 166 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/TrustValidator.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/TrustValidator.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/TrustValidator.java
index 719df01..ed31f44 100644
--- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/TrustValidator.java
+++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/TrustValidator.java
@@ -20,6 +20,8 @@ package org.apache.cxf.rs.security.common;
 
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.regex.Pattern;
 
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.ext.WSSecurityException;
@@ -30,9 +32,16 @@ import org.apache.wss4j.dom.validate.SignatureTrustValidator;
 public class TrustValidator {
     public void validateTrust(Crypto crypto, X509Certificate cert, PublicKey publicKey) 
         throws WSSecurityException {
+        validateTrust(crypto, cert, publicKey, null);
+    }
+    
+    public void validateTrust(Crypto crypto, X509Certificate cert, PublicKey publicKey,
+                              Collection<Pattern> subjectCertConstraints) 
+        throws WSSecurityException {
         SignatureTrustValidator validator = new SignatureTrustValidator();
         RequestData data = new RequestData();
         data.setSigVerCrypto(crypto);
+        data.setSubjectCertConstraints(subjectCertConstraints);
         
         Credential trustCredential = new Credential();
         trustCredential.setPublicKey(publicKey);

http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
index e81e298..3875e61 100644
--- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
+++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java
@@ -22,13 +22,17 @@ package org.apache.cxf.rs.security.xml;
 import java.io.InputStream;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 import javax.xml.stream.XMLStreamReader;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.rs.security.common.CryptoLoader;
@@ -54,6 +58,10 @@ public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler {
     private boolean persistSignature = true;
     private boolean keyInfoMustBeAvailable = true;
     private SignatureProperties sigProps;
+    /**
+     * a collection of compiled regular expression patterns for the subject DN
+     */
+    private Collection<Pattern> subjectDNPatterns = new ArrayList<Pattern>();
     
     public void setRemoveSignature(boolean remove) {
         this.removeSignature = remove;
@@ -144,7 +152,7 @@ public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler {
             }
             
             // validate trust 
-            new TrustValidator().validateTrust(crypto, cert, publicKey);
+            new TrustValidator().validateTrust(crypto, cert, publicKey, subjectDNPatterns);
             if (valid && persistSignature) {
                 message.setContent(XMLSignature.class, signature);
                 message.setContent(Element.class, signedElement);
@@ -370,4 +378,22 @@ public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler {
     public void setKeyInfoMustBeAvailable(boolean use) {
         this.keyInfoMustBeAvailable = use;
     }
+    
+    /**
+     * Set a list of Strings corresponding to regular expression constraints on the subject DN
+     * of a certificate
+     */
+    public void setSubjectConstraints(List<String> constraints) {
+        if (constraints != null) {
+            subjectDNPatterns = new ArrayList<Pattern>();
+            for (String constraint : constraints) {
+                try {
+                    subjectDNPatterns.add(Pattern.compile(constraint.trim()));
+                } catch (PatternSyntaxException ex) {
+                    throw ex;
+                }
+            }
+        }
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java
index 00221c1..03c4dd9 100644
--- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java
+++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java
@@ -23,9 +23,13 @@ import java.io.InputStream;
 import java.security.Key;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
@@ -78,6 +82,10 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> {
     private boolean persistSignature = true;
     private boolean requireSignature;
     private boolean requireEncryption;
+    /**
+     * a collection of compiled regular expression patterns for the subject DN
+     */
+    private Collection<Pattern> subjectDNPatterns = new ArrayList<Pattern>();
 
     public XmlSecInInterceptor() {
         super(Phase.POST_STREAM);
@@ -289,7 +297,7 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> {
             
             // validate trust 
             try {
-                new TrustValidator().validateTrust(sigCrypto, cert, publicKey);
+                new TrustValidator().validateTrust(sigCrypto, cert, publicKey, subjectDNPatterns);
             } catch (WSSecurityException e) {
                 throw new XMLSecurityException("empty", "Error during Signature Trust "
                                                + "validation: " + e.getMessage());
@@ -352,6 +360,23 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> {
     }
     
     /**
+     * Set a list of Strings corresponding to regular expression constraints on the subject DN
+     * of a certificate
+     */
+    public void setSubjectConstraints(List<String> constraints) {
+        if (constraints != null) {
+            subjectDNPatterns = new ArrayList<Pattern>();
+            for (String constraint : constraints) {
+                try {
+                    subjectDNPatterns.add(Pattern.compile(constraint.trim()));
+                } catch (PatternSyntaxException ex) {
+                    throw ex;
+                }
+            }
+        }
+    }
+    
+    /**
      * This interceptor handles parsing the StaX results (events) + checks to see whether the 
      * required (if any) Actions (signature or encryption) were fulfilled.
      */

http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
index cbf411b..64e14ca 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
@@ -101,8 +101,45 @@ public class JAXRSXmlSecTest extends AbstractBusClientServerTestBase {
         doTestSignatureProxy(address, true, "file:", test.streaming);
     }
     
+    @Test
+    public void testCertConstraints() throws Exception {
+        String address = "https://localhost:" + test.port + "/xmlsigconstraints";
+        
+        // Successful test with "bob"
+        Map<String, Object> newProperties = new HashMap<String, Object>();
+        newProperties.put("ws-security.callback-handler", 
+            "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+        newProperties.put("ws-security.signature.username", "bob");
+
+        String cryptoUrl = "org/apache/cxf/systest/jaxrs/security/bob.properties";
+        newProperties.put("ws-security.signature.properties", cryptoUrl);
+        doTestSignatureProxy(address, false, null, test.streaming, newProperties);
+        
+        // Constraint validation fails with "alice"
+        newProperties.clear();
+        newProperties.put("ws-security.callback-handler", 
+            "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+        newProperties.put("ws-security.signature.username", "alice");
+
+        cryptoUrl = "org/apache/cxf/systest/jaxrs/security/alice.properties";
+        newProperties.put("ws-security.signature.properties", cryptoUrl);
+        try {
+            doTestSignatureProxy(address, false, null, test.streaming, newProperties);
+            fail("Failure expected on a failing cert constraint");
+        } catch (Exception ex) {
+            // expected
+        }
+    }
+    
     private void doTestSignatureProxy(String address, boolean enveloping,
                                       String cryptoUrlPrefix, boolean streaming) throws Exception {
+        doTestSignatureProxy(address, enveloping, cryptoUrlPrefix, 
+                             streaming, new HashMap<String, Object>());
+    }
+    
+    private void doTestSignatureProxy(String address, boolean enveloping,
+                                      String cryptoUrlPrefix, boolean streaming,
+                                      Map<String, Object> properties) throws Exception {
         JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
         bean.setAddress(address);
         
@@ -111,17 +148,19 @@ public class JAXRSXmlSecTest extends AbstractBusClientServerTestBase {
         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.signature.username", "alice");
-        
-        String cryptoUrl = "org/apache/cxf/systest/jaxrs/security/alice.properties";
-        if (cryptoUrlPrefix != null) {
-            cryptoUrl = cryptoUrlPrefix + this.getClass().getResource("/" + cryptoUrl).toURI().getPath();
+        Map<String, Object> newProperties = new HashMap<String, Object>(properties);
+        if (newProperties.isEmpty()) {
+            newProperties.put("ws-security.callback-handler", 
+                           "org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback");
+            newProperties.put("ws-security.signature.username", "alice");
+            
+            String cryptoUrl = "org/apache/cxf/systest/jaxrs/security/alice.properties";
+            if (cryptoUrlPrefix != null) {
+                cryptoUrl = cryptoUrlPrefix + this.getClass().getResource("/" + cryptoUrl).toURI().getPath();
+            }
+            newProperties.put("ws-security.signature.properties", cryptoUrl);
         }
-        properties.put("ws-security.signature.properties", cryptoUrl);
-        bean.setProperties(properties);
+        bean.setProperties(newProperties);
         
         if (streaming) {
             XmlSecOutInterceptor sigInterceptor = new XmlSecOutInterceptor();
@@ -137,18 +176,8 @@ public class JAXRSXmlSecTest extends AbstractBusClientServerTestBase {
         bean.setServiceClass(BookStore.class);
         
         BookStore store = bean.create(BookStore.class);
-        try {
-            Book book = store.addBook(new Book("CXF", 126L));
-            assertEquals(126L, book.getId());
-        } catch (WebApplicationException ex) {
-            fail(ex.getMessage());
-        } catch (ProcessingException ex) {
-            if (ex.getCause() != null && ex.getCause().getMessage() != null) {
-                fail(ex.getCause().getMessage());
-            } else {
-                fail(ex.getMessage());
-            }
-        }
+        Book book = store.addBook(new Book("CXF", 126L));
+        assertEquals(126L, book.getId());
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
index f5516e8..80779fa 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/server.xml
@@ -17,7 +17,7 @@ KIND, either express or implied. See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://cxf.apache.org/transports/http/configuration" 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         http://cxf.apache.org/transports/http-jetty/configuration   http://cxf.apache.org/schemas/configuration/http-jetty.xsd         http://cxf.apache.org/configuration/security    
             http://cxf.apache.org/schemas/configuration/security.xsd         ">
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://cxf.apache.org/transports/http/configuration" 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" xmlns:util="http://www.springframework.org/schema/util" 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         http://cxf.apache.org/transports/http-jetty/configuration   http://cxf.apache.org/schemas/configuration/http-jetty.xsd 
         http://cxf.apache.org/configuration/security                http://cxf.apache.org/schemas/configuration/security.xsd         http://www.springframework.org/schema/util         http://www.springframework.org/schema/util/spring-util-2.0.xsd">
     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
     <cxf:bus>
         <cxf:features>
@@ -56,7 +56,15 @@ under the License.
         <property name="encryptionKeyTransportAlgo" value="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
         <property name="encryptionSymmetricKeyAlgo" value="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
     </bean>
-    <bean id="xmlSigInHandler" class="org.apache.cxf.rs.security.xml.XmlSigInHandler"/>
+    <bean id="xmlSigInHandler" class="org.apache.cxf.rs.security.xml.XmlSigInHandler">
+    </bean>
+    <bean id="xmlSigInHandlerConstraints" class="org.apache.cxf.rs.security.xml.XmlSigInHandler">
+        <property name="subjectConstraints">
+            <util:list>
+                <value>.*CN=bob.*</value>
+            </util:list>
+        </property>
+    </bean>
     <bean id="xmlSigInHandlerWithProps" class="org.apache.cxf.rs.security.xml.XmlSigInHandler">
         <property name="signatureProperties" ref="sigProps"/>
     </bean>
@@ -96,6 +104,22 @@ under the License.
         </jaxrs:properties>
     </jaxrs:server>
     
+    <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlsigconstraints">
+        <jaxrs:serviceBeans>
+            <ref bean="serviceBean"/>
+        </jaxrs:serviceBeans>
+        <jaxrs:providers>
+            <ref bean="xmlSigInHandlerConstraints"/>
+        </jaxrs:providers>
+        <jaxrs:outInterceptors>
+            <ref bean="xmlSigOutHandler"/>
+        </jaxrs:outInterceptors>
+        <jaxrs:properties>
+            <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback"/>
+            <entry key="ws-security.signature.properties" value="org/apache/cxf/systest/jaxrs/security/bob.properties"/>
+        </jaxrs:properties>
+    </jaxrs:server>
+    
     <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-xmlsec}/xmlsignokeyinfo">
         <jaxrs:serviceBeans>
             <ref bean="serviceBean"/>

http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml
index 59e9b89..54df27d 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/stax-server.xml
@@ -17,7 +17,7 @@ KIND, either express or implied. See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://cxf.apache.org/transports/http/configuration" 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         http://cxf.apache.org/transports/http-jetty/configuration   http://cxf.apache.org/schemas/configuration/http-jetty.xsd         http://cxf.apache.org/configuration/security    
             http://cxf.apache.org/schemas/configuration/security.xsd         ">
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://cxf.apache.org/transports/http/configuration" 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" xmlns:util="http://www.springframework.org/schema/util" 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         http://cxf.apache.org/transports/http-jetty/configuration   http://cxf.apache.org/schemas/configuration/http-jetty.xsd 
         http://cxf.apache.org/configuration/security                http://cxf.apache.org/schemas/configuration/security.xsd         http://www.springframework.org/schema/util         http://www.springframework.org/schema/util/spring-util-2.0.xsd">
     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
     <cxf:bus>
         <cxf:features>
@@ -60,6 +60,15 @@ under the License.
         <property name="requireSignature" value="true"/>
         <property name="signatureVerificationAlias" value="alice" />
     </bean>
+    <bean id="xmlSigInHandlerConstraints" class="org.apache.cxf.rs.security.xml.XmlSecInInterceptor">
+        <property name="requireSignature" value="true"/>
+        <property name="signatureVerificationAlias" value="alice" />
+        <property name="subjectConstraints">
+            <util:list>
+                <value>.*CN=bob.*</value>
+            </util:list>
+        </property>
+    </bean>
     <bean id="xmlEncInHandler" class="org.apache.cxf.rs.security.xml.XmlSecInInterceptor">
         <property name="decryptionAlias" value="bob" />
         <property name="requireEncryption" value="true"/>
@@ -115,6 +124,22 @@ under the License.
         </jaxrs:properties>
     </jaxrs:server>
     
+     <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-xmlsec-stax}/xmlsigconstraints">
+        <jaxrs:serviceBeans>
+            <ref bean="serviceBean"/>
+        </jaxrs:serviceBeans>
+        <jaxrs:inInterceptors>
+            <ref bean="xmlSigInHandlerConstraints"/>
+        </jaxrs:inInterceptors>
+        <jaxrs:outInterceptors>
+            <ref bean="xmlSigOutHandler"/>
+        </jaxrs:outInterceptors>
+        <jaxrs:properties>
+            <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.jaxrs.security.saml.KeystorePasswordCallback"/>
+            <entry key="ws-security.signature.properties" value="org/apache/cxf/systest/jaxrs/security/bob.properties"/>
+        </jaxrs:properties>
+    </jaxrs:server>
+    
     <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-xmlsec-stax}/xmlsignokeyinfo">
         <jaxrs:serviceBeans>
             <ref bean="serviceBean"/>

http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/alice.jks
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/alice.jks b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/alice.jks
index 3a788c2..9f47a5c 100644
Binary files a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/alice.jks and b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/alice.jks differ

http://git-wip-us.apache.org/repos/asf/cxf/blob/fac67a20/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks
index a4f49c5..26df583 100644
Binary files a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks and b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/bob.jks differ