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 2014/10/22 17:04:19 UTC

git commit: [CXF-6053] Adding JAXRS JwsJson filters and starting with the system testing

Repository: cxf
Updated Branches:
  refs/heads/master f2fd3cc07 -> 1858ea6bc


[CXF-6053] Adding JAXRS JwsJson filters and starting with the system testing


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

Branch: refs/heads/master
Commit: 1858ea6bc44e4eb1f50325dd5680b26dfd27964f
Parents: f2fd3cc
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Wed Oct 22 16:04:01 2014 +0100
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Wed Oct 22 16:04:01 2014 +0100

----------------------------------------------------------------------
 .../cxf/rs/security/jose/JoseConstants.java     |   1 +
 .../jose/jaxrs/AbstractJweDecryptingFilter.java |  65 +-----------
 .../jaxrs/AbstractJwsJsonReaderProvider.java    |  77 ++++++++++++++
 .../jaxrs/AbstractJwsJsonWriterProvider.java    |  79 ++++++++++++++
 .../jose/jaxrs/AbstractJwsReaderProvider.java   |  34 +-----
 .../jose/jaxrs/AbstractJwsWriterProvider.java   |  38 +------
 .../jose/jaxrs/JweWriterInterceptor.java        |  77 +-------------
 .../jose/jaxrs/JwsJsonClientResponseFilter.java |  57 ++++++++++
 .../jaxrs/JwsJsonContainerRequestFilter.java    |  60 +++++++++++
 .../jose/jaxrs/JwsJsonWriterInterceptor.java    |  80 ++++++++++++++
 .../jose/jaxrs/JwsWriterInterceptor.java        |   4 +-
 .../cxf/rs/security/jose/jwa/Algorithm.java     |  26 +++--
 .../cxf/rs/security/jose/jwe/JweUtils.java      | 105 +++++++++++++++++++
 .../rs/security/jose/jws/JwsJsonConsumer.java   |  63 +++++++++--
 .../rs/security/jose/jws/JwsJsonProducer.java   |  11 ++
 .../jose/jws/JwsJsonSignatureEntry.java         |   3 +
 .../cxf/rs/security/jose/jws/JwsUtils.java      |  68 +++++++++++-
 .../security/jose/jws/JwsJsonConsumerTest.java  |   4 +-
 .../jaxrs/security/jwt/BookServerJwsJson.java   |  57 ++++++++++
 .../jaxrs/security/jwt/JAXRSJwsJsonTest.java    |  66 ++++++++++++
 .../jaxrs/security/jwt/serverJwsJson.xml        |  62 +++++++++++
 21 files changed, 811 insertions(+), 226 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
index a0b6a5b..6d95234 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java
@@ -41,6 +41,7 @@ public final class JoseConstants {
     public static final String TYPE_JWT = "JWT";
     public static final String TYPE_JOSE = "JOSE";
     public static final String TYPE_JOSE_JSON = "JOSE+JSON";
+    public static final String MEDIA_TYPE_JOSE = "application/jose";
     public static final String MEDIA_TYPE_JOSE_JSON = "application/jose+json";
     
     public static final String PLAIN_TEXT_ALGO = "none";

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
index a1bd5cf..83e00e1 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
@@ -20,36 +20,19 @@ package org.apache.cxf.rs.security.jose.jaxrs;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.security.interfaces.RSAPrivateKey;
-import java.util.Properties;
 
-import javax.crypto.SecretKey;
-
-import org.apache.cxf.Bus;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
-import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
-import org.apache.cxf.rs.security.jose.jwa.Algorithm;
-import org.apache.cxf.rs.security.jose.jwe.AesCbcHmacJweDecryption;
-import org.apache.cxf.rs.security.jose.jwe.AesGcmContentDecryptionAlgorithm;
-import org.apache.cxf.rs.security.jose.jwe.DirectKeyJweDecryption;
 import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput;
 import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
 import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
 import org.apache.cxf.rs.security.jose.jwe.JweUtils;
-import org.apache.cxf.rs.security.jose.jwe.KeyDecryptionAlgorithm;
-import org.apache.cxf.rs.security.jose.jwe.RSAOaepKeyDecryptionAlgorithm;
-import org.apache.cxf.rs.security.jose.jwe.WrappedKeyJweDecryption;
-import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
-import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
 
 public class AbstractJweDecryptingFilter {
     private static final String RSSEC_ENCRYPTION_IN_PROPS = "rs.security.encryption.in.properties";
     private static final String RSSEC_ENCRYPTION_PROPS = "rs.security.encryption.properties";
-    private static final String JSON_WEB_ENCRYPTION_KEY_ALGO_PROP = "rs.security.jwe.key.encryption.algorithm";
-    private static final String JSON_WEB_ENCRYPTION_CEK_ALGO_PROP = "rs.security.jwe.content.encryption.algorithm";    
     private JweDecryptionProvider decryption;
     private String defaultMediaType;
     protected JweDecryptionOutput decrypt(InputStream is) throws IOException {
@@ -75,53 +58,7 @@ public class AbstractJweDecryptingFilter {
         if (propLoc == null) {
             throw new SecurityException();
         }
-        Bus bus = m.getExchange().getBus();
-        try {
-            KeyDecryptionAlgorithm keyDecryptionProvider = null;
-            Properties props = ResourceUtils.loadProperties(propLoc, bus);
-            String contentEncryptionAlgo = props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP);
-            SecretKey ctDecryptionKey = null;
-            if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
-                JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_ENCRYPT);
-                String keyEncryptionAlgo = getKeyEncryptionAlgo(props, jwk.getAlgorithm());
-                if ("direct".equals(keyEncryptionAlgo)) {
-                    contentEncryptionAlgo = getContentEncryptionAlgo(props, contentEncryptionAlgo);
-                    ctDecryptionKey = JweUtils.getContentDecryptionSecretKey(jwk, contentEncryptionAlgo);
-                } else {
-                    keyDecryptionProvider = JweUtils.getKeyDecryptionAlgorithm(jwk, keyEncryptionAlgo);
-                }
-            } else {
-                keyDecryptionProvider = new RSAOaepKeyDecryptionAlgorithm(
-                    (RSAPrivateKey)KeyManagementUtils.loadPrivateKey(
-                        m, props, KeyManagementUtils.RSSEC_DECRYPT_KEY_PSWD_PROVIDER));
-            }
-            if (keyDecryptionProvider == null && ctDecryptionKey == null) {
-                throw new SecurityException();
-            }
-            if (keyDecryptionProvider != null) {
-                if (Algorithm.isAesCbcHmac(contentEncryptionAlgo)) { 
-                    return new AesCbcHmacJweDecryption(keyDecryptionProvider, contentEncryptionAlgo);
-                } else {
-                    return new WrappedKeyJweDecryption(keyDecryptionProvider, 
-                                                       new AesGcmContentDecryptionAlgorithm(contentEncryptionAlgo));
-                }
-            } else {
-                return new DirectKeyJweDecryption(ctDecryptionKey, 
-                                                  new AesGcmContentDecryptionAlgorithm(contentEncryptionAlgo));
-            }
-        } catch (SecurityException ex) {
-            throw ex;
-        } catch (Exception ex) {
-            throw new SecurityException(ex);
-        }
-        
-    }
-    
-    private String getKeyEncryptionAlgo(Properties props, String algo) {
-        return algo == null ? props.getProperty(JSON_WEB_ENCRYPTION_KEY_ALGO_PROP) : algo;
-    }
-    private String getContentEncryptionAlgo(Properties props, String algo) {
-        return algo == null ? props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP) : algo;
+        return JweUtils.loadDecryptionProvider(propLoc, m);
     }
     public String getDefaultMediaType() {
         return defaultMediaType;

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
new file mode 100644
index 0000000..bf2bf2f
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
@@ -0,0 +1,77 @@
+/**
+ * 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.rs.security.jose.jaxrs;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
+import org.apache.cxf.rs.security.jose.jws.JwsUtils;
+
+public class AbstractJwsJsonReaderProvider {
+    private static final String RSSEC_SIGNATURE_IN_LIST_PROPS = "rs.security.signature.in.list.properties";
+    private static final String RSSEC_SIGNATURE_LIST_PROPS = "rs.security.signature.list.properties";
+    
+    private List<JwsSignatureVerifier> sigVerifiers;
+    private String defaultMediaType;
+    
+    public void setSignatureVerifier(JwsSignatureVerifier signatureVerifier) {
+        setSignatureVerifiers(Collections.singletonList(signatureVerifier));
+    }
+    public void setSignatureVerifiers(List<JwsSignatureVerifier> signatureVerifiers) {
+        this.sigVerifiers = signatureVerifiers;
+    }
+
+    protected List<JwsSignatureVerifier> getInitializedSigVerifiers() {
+        if (sigVerifiers != null) {
+            return sigVerifiers;    
+        }
+        Message m = JAXRSUtils.getCurrentMessage();
+        Object propLocsProp = 
+            MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_IN_LIST_PROPS, RSSEC_SIGNATURE_LIST_PROPS);
+        if (propLocsProp == null) {
+            throw new SecurityException();
+        }
+        List<String> propLocs = null;
+        if (propLocsProp instanceof String) { 
+            propLocs = Collections.singletonList((String)propLocsProp);
+        } else {
+            propLocs = CastUtils.cast((List<?>)propLocsProp);
+        }
+        List<JwsSignatureVerifier> theSigVerifiers = new LinkedList<JwsSignatureVerifier>();
+        for (String propLoc : propLocs) {
+            theSigVerifiers.add(JwsUtils.loadSignatureVerifier(propLoc, m));
+        }
+        return theSigVerifiers;
+    }
+
+    public String getDefaultMediaType() {
+        return defaultMediaType;
+    }
+
+    public void setDefaultMediaType(String defaultMediaType) {
+        this.defaultMediaType = defaultMediaType;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
new file mode 100644
index 0000000..6aa9695
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
@@ -0,0 +1,79 @@
+/**
+ * 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.rs.security.jose.jaxrs;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.rs.security.jose.jws.JwsJsonProducer;
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
+import org.apache.cxf.rs.security.jose.jws.JwsUtils;
+
+public class AbstractJwsJsonWriterProvider {
+    private static final String RSSEC_SIGNATURE_OUT_LIST_PROPS = "rs.security.signature.out.list.properties";
+    private static final String RSSEC_SIGNATURE_LIST_PROPS = "rs.security.signature.list.properties";
+    
+    private List<JwsSignatureProvider> sigProviders;
+    
+    public void setSignatureProvider(JwsSignatureProvider signatureProvider) {
+        setSignatureProviders(Collections.singletonList(signatureProvider));
+    }
+    public void setSignatureProviders(List<JwsSignatureProvider> signatureProviders) {
+        this.sigProviders = signatureProviders;
+    }
+    
+    protected List<JwsSignatureProvider> getInitializedSigProviders() {
+        if (sigProviders != null) {
+            return sigProviders;    
+        } 
+        Message m = JAXRSUtils.getCurrentMessage();
+        Object propLocsProp = 
+            MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_OUT_LIST_PROPS, RSSEC_SIGNATURE_LIST_PROPS);
+        if (propLocsProp == null) {
+            throw new SecurityException();
+        }
+        List<String> propLocs = null;
+        if (propLocsProp instanceof String) { 
+            propLocs = Collections.singletonList((String)propLocsProp);
+        } else {
+            propLocs = CastUtils.cast((List<?>)propLocsProp);
+        }
+        List<JwsSignatureProvider> theSigProviders = new LinkedList<JwsSignatureProvider>();
+        for (String propLoc : propLocs) {
+            theSigProviders.add(JwsUtils.loadSignatureProvider(propLoc, m));
+        }
+        return theSigProviders;
+    }
+    protected void writeJws(JwsJsonProducer p, OutputStream os) 
+        throws IOException {
+        byte[] bytes = StringUtils.toBytesUTF8(p.getJwsJsonSignedDocument());
+        IOUtils.copy(new ByteArrayInputStream(bytes), os);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
index 6902e97..6027e60 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
@@ -18,25 +18,15 @@
  */
 package org.apache.cxf.rs.security.jose.jaxrs;
 
-import java.security.interfaces.RSAPublicKey;
-import java.util.Properties;
-
-import org.apache.cxf.Bus;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
-import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
-import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
-import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
 import org.apache.cxf.rs.security.jose.jws.JwsUtils;
-import org.apache.cxf.rs.security.jose.jws.PublicKeyJwsSignatureVerifier;
 
 public class AbstractJwsReaderProvider {
     private static final String RSSEC_SIGNATURE_IN_PROPS = "rs.security.signature.in.properties";
     private static final String RSSEC_SIGNATURE_PROPS = "rs.security.signature.properties";
-    private static final String JSON_WEB_SIGNATURE_ALGO_PROP = "rs.security.jws.content.signature.algorithm";
-    
     
     private JwsSignatureVerifier sigVerifier;
     private String defaultMediaType;
@@ -56,26 +46,7 @@ public class AbstractJwsReaderProvider {
         if (propLoc == null) {
             throw new SecurityException();
         }
-        Bus bus = m.getExchange().getBus();
-        try {
-            Properties props = ResourceUtils.loadProperties(propLoc, bus);
-            JwsSignatureVerifier theVerifier = null;
-            String rsaSignatureAlgo = null;
-            if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
-                JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_VERIFY);
-                rsaSignatureAlgo = getSignatureAlgo(props, jwk.getAlgorithm());
-                theVerifier = JwsUtils.getSignatureVerifier(jwk, rsaSignatureAlgo);
-                
-            } else {
-                theVerifier = new PublicKeyJwsSignatureVerifier(
-                                  (RSAPublicKey)KeyManagementUtils.loadPublicKey(m, props));
-            }
-            return theVerifier;
-        } catch (SecurityException ex) {
-            throw ex;
-        } catch (Exception ex) {
-            throw new SecurityException(ex);
-        }
+        return JwsUtils.loadSignatureVerifier(propLoc, m);
     }
 
     public String getDefaultMediaType() {
@@ -86,7 +57,4 @@ public class AbstractJwsReaderProvider {
         this.defaultMediaType = defaultMediaType;
     }
     
-    private String getSignatureAlgo(Properties props, String algo) {
-        return algo == null ? props.getProperty(JSON_WEB_SIGNATURE_ALGO_PROP) : algo;
-    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
index 8f5b1a0..ff0a5aa 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java
@@ -21,27 +21,20 @@ package org.apache.cxf.rs.security.jose.jaxrs;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.security.interfaces.RSAPrivateKey;
-import java.util.Properties;
 
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
-import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.rs.security.jose.JoseHeaders;
-import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
-import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
 import org.apache.cxf.rs.security.jose.jws.JwsCompactProducer;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 import org.apache.cxf.rs.security.jose.jws.JwsUtils;
-import org.apache.cxf.rs.security.jose.jws.PrivateKeyJwsSignatureProvider;
 
 public class AbstractJwsWriterProvider {
     private static final String RSSEC_SIGNATURE_OUT_PROPS = "rs.security.signature.out.properties";
     private static final String RSSEC_SIGNATURE_PROPS = "rs.security.signature.properties";
-    private static final String JSON_WEB_SIGNATURE_ALGO_PROP = "rs.security.jws.content.signature.algorithm";
     
     private JwsSignatureProvider sigProvider;
     
@@ -59,30 +52,9 @@ public class AbstractJwsWriterProvider {
         if (propLoc == null) {
             throw new SecurityException();
         }
-        try {
-            Properties props = ResourceUtils.loadProperties(propLoc, m.getExchange().getBus());
-            JwsSignatureProvider theSigProvider = null; 
-            String rsaSignatureAlgo = null;
-            if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
-                JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_SIGN);
-                rsaSignatureAlgo = getSignatureAlgo(props, jwk.getAlgorithm());
-                theSigProvider = JwsUtils.getSignatureProvider(jwk, rsaSignatureAlgo);
-            } else {
-                rsaSignatureAlgo = getSignatureAlgo(props, null);
-                RSAPrivateKey pk = (RSAPrivateKey)KeyManagementUtils.loadPrivateKey(m, props, 
-                    KeyManagementUtils.RSSEC_SIG_KEY_PSWD_PROVIDER);
-                theSigProvider = new PrivateKeyJwsSignatureProvider(pk, rsaSignatureAlgo);
-            }
-            if (theSigProvider == null) {
-                throw new SecurityException();
-            }
-            headers.setAlgorithm(rsaSignatureAlgo);
-            return theSigProvider;
-        } catch (SecurityException ex) {
-            throw ex;
-        } catch (Exception ex) {
-            throw new SecurityException(ex);
-        }
+        JwsSignatureProvider theSigProvider = JwsUtils.loadSignatureProvider(propLoc, m); 
+        headers.setAlgorithm(theSigProvider.getAlgorithm());
+        return theSigProvider;
     }
     protected void writeJws(JwsCompactProducer p, JwsSignatureProvider theSigProvider, OutputStream os) 
         throws IOException {
@@ -90,7 +62,5 @@ public class AbstractJwsWriterProvider {
         byte[] bytes = StringUtils.toBytesUTF8(p.getSignedEncodedJws());
         IOUtils.copy(new ByteArrayInputStream(bytes), os);
     }
-    private String getSignatureAlgo(Properties props, String algo) {
-        return algo == null ? props.getProperty(JSON_WEB_SIGNATURE_ALGO_PROP) : algo;
-    }
+    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
index 10f82e3..9ae670e 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
@@ -21,8 +21,6 @@ package org.apache.cxf.rs.security.jose.jaxrs;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.security.interfaces.RSAPublicKey;
-import java.util.Properties;
 import java.util.zip.DeflaterOutputStream;
 
 import javax.annotation.Priority;
@@ -31,41 +29,25 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.ext.WriterInterceptor;
 import javax.ws.rs.ext.WriterInterceptorContext;
 
-import org.apache.cxf.Bus;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
-import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.rs.security.jose.JoseConstants;
 import org.apache.cxf.rs.security.jose.JoseHeadersReaderWriter;
 import org.apache.cxf.rs.security.jose.JoseHeadersWriter;
-import org.apache.cxf.rs.security.jose.jwa.Algorithm;
-import org.apache.cxf.rs.security.jose.jwe.AesCbcHmacJweEncryption;
-import org.apache.cxf.rs.security.jose.jwe.AesGcmContentEncryptionAlgorithm;
-import org.apache.cxf.rs.security.jose.jwe.ContentEncryptionAlgorithm;
-import org.apache.cxf.rs.security.jose.jwe.DirectKeyJweEncryption;
 import org.apache.cxf.rs.security.jose.jwe.JweCompactProducer;
 import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
 import org.apache.cxf.rs.security.jose.jwe.JweEncryptionState;
-import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
 import org.apache.cxf.rs.security.jose.jwe.JweOutputStream;
 import org.apache.cxf.rs.security.jose.jwe.JweUtils;
-import org.apache.cxf.rs.security.jose.jwe.KeyEncryptionAlgorithm;
-import org.apache.cxf.rs.security.jose.jwe.RSAOaepKeyEncryptionAlgorithm;
-import org.apache.cxf.rs.security.jose.jwe.WrappedKeyJweEncryption;
-import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
-import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
 
 @Priority(Priorities.JWE_WRITE_PRIORITY)
 public class JweWriterInterceptor implements WriterInterceptor {
     private static final String RSSEC_ENCRYPTION_OUT_PROPS = "rs.security.encryption.out.properties";
     private static final String RSSEC_ENCRYPTION_PROPS = "rs.security.encryption.properties";
-    private static final String JSON_WEB_ENCRYPTION_CEK_ALGO_PROP = "rs.security.jwe.content.encryption.algorithm";
-    private static final String JSON_WEB_ENCRYPTION_KEY_ALGO_PROP = "rs.security.jwe.key.encryption.algorithm";
-    private static final String JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP = "rs.security.jwe.zip.algorithm";
     private JweEncryptionProvider encryptionProvider;
     private boolean contentTypeRequired = true;
     private boolean useJweOutputStream;
@@ -89,7 +71,7 @@ public class JweWriterInterceptor implements WriterInterceptor {
             }
         }
         
-        ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE_JSON));
+        ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE));
         if (useJweOutputStream) {
             JweEncryptionState encryption = theEncryptionProvider.createJweEncryptionState(ctString);
             try {
@@ -131,62 +113,9 @@ public class JweWriterInterceptor implements WriterInterceptor {
         if (propLoc == null) {
             throw new SecurityException();
         }
-        Bus bus = m.getExchange().getBus();
-        try {
-            KeyEncryptionAlgorithm keyEncryptionProvider = null;
-            String keyEncryptionAlgo = null;
-            Properties props = ResourceUtils.loadProperties(propLoc, bus);
-            String contentEncryptionAlgo = props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP);
-            ContentEncryptionAlgorithm ctEncryptionProvider = null;
-            if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
-                JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_ENCRYPT);
-                keyEncryptionAlgo = getKeyEncryptionAlgo(props, jwk.getAlgorithm());
-                if ("direct".equals(keyEncryptionAlgo)) {
-                    contentEncryptionAlgo = getContentEncryptionAlgo(props, jwk.getAlgorithm());
-                    ctEncryptionProvider = JweUtils.getContentEncryptionAlgorithm(jwk, contentEncryptionAlgo);
-                } else {
-                    keyEncryptionProvider = JweUtils.getKeyEncryptionAlgorithm(jwk, keyEncryptionAlgo);
-                }
-                
-            } else {
-                keyEncryptionProvider = new RSAOaepKeyEncryptionAlgorithm(
-                    (RSAPublicKey)KeyManagementUtils.loadPublicKey(m, props), 
-                    getKeyEncryptionAlgo(props, keyEncryptionAlgo));
-            }
-            if (keyEncryptionProvider == null && ctEncryptionProvider == null) {
-                throw new SecurityException();
-            }
-            
-            
-            JweHeaders headers = new JweHeaders(getKeyEncryptionAlgo(props, keyEncryptionAlgo), 
-                                                contentEncryptionAlgo);
-            String compression = props.getProperty(JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP);
-            if (compression != null) {
-                headers.setZipAlgorithm(compression);
-            }
-            if (keyEncryptionProvider != null) {
-                if (Algorithm.isAesCbcHmac(contentEncryptionAlgo)) { 
-                    return new AesCbcHmacJweEncryption(contentEncryptionAlgo, keyEncryptionProvider);
-                } else {
-                    return new WrappedKeyJweEncryption(headers, 
-                                                       keyEncryptionProvider,
-                                                       new AesGcmContentEncryptionAlgorithm(contentEncryptionAlgo));
-                }
-            } else {
-                return new DirectKeyJweEncryption(ctEncryptionProvider);
-            }
-        } catch (SecurityException ex) {
-            throw ex;
-        } catch (Exception ex) {
-            throw new SecurityException(ex);
-        }
-    }
-    private String getKeyEncryptionAlgo(Properties props, String algo) {
-        return algo == null ? props.getProperty(JSON_WEB_ENCRYPTION_KEY_ALGO_PROP) : algo;
-    }
-    private String getContentEncryptionAlgo(Properties props, String algo) {
-        return algo == null ? props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP) : algo;
+        return JweUtils.loadEncryptionProvider(propLoc, m);
     }
+    
     public void setUseJweOutputStream(boolean useJweOutputStream) {
         this.useJweOutputStream = useJweOutputStream;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonClientResponseFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonClientResponseFilter.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonClientResponseFilter.java
new file mode 100644
index 0000000..273aba1
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonClientResponseFilter.java
@@ -0,0 +1,57 @@
+/**
+ * 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.rs.security.jose.jaxrs;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.List;
+
+import javax.annotation.Priority;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.rs.security.jose.JoseUtils;
+import org.apache.cxf.rs.security.jose.jws.JwsJsonConsumer;
+import org.apache.cxf.rs.security.jose.jws.JwsJsonSignatureEntry;
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
+
+@Priority(Priorities.JWS_CLIENT_READ_PRIORITY)
+public class JwsJsonClientResponseFilter extends AbstractJwsJsonReaderProvider implements ClientResponseFilter {
+    @Override
+    public void filter(ClientRequestContext req, ClientResponseContext res) throws IOException {
+        List<JwsSignatureVerifier> theSigVerifiers = getInitializedSigVerifiers();
+        JwsJsonConsumer p = new JwsJsonConsumer(IOUtils.readStringFromStream(res.getEntityStream()));
+        if (!p.verifySignatureWith(theSigVerifiers)) {
+            throw new SecurityException();
+        }
+        byte[] bytes = p.getDecodedJwsPayloadBytes();
+        res.setEntityStream(new ByteArrayInputStream(bytes));
+        res.getHeaders().putSingle("Content-Length", Integer.toString(bytes.length));
+        
+        // the list is guaranteed to be non-empty
+        JwsJsonSignatureEntry sigEntry = p.getSignatureEntries().get(0);
+        String ct = JoseUtils.checkContentType(sigEntry.getUnionHeader().getContentType(), getDefaultMediaType());
+        if (ct != null) {
+            res.getHeaders().putSingle("Content-Type", ct);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonContainerRequestFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonContainerRequestFilter.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonContainerRequestFilter.java
new file mode 100644
index 0000000..6b7ffdf
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonContainerRequestFilter.java
@@ -0,0 +1,60 @@
+/**
+ * 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.rs.security.jose.jaxrs;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.List;
+
+import javax.annotation.Priority;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.rs.security.jose.JoseUtils;
+import org.apache.cxf.rs.security.jose.jws.JwsJsonConsumer;
+import org.apache.cxf.rs.security.jose.jws.JwsJsonSignatureEntry;
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
+
+@PreMatching
+@Priority(Priorities.JWS_SERVER_READ_PRIORITY)
+public class JwsJsonContainerRequestFilter extends AbstractJwsJsonReaderProvider implements ContainerRequestFilter {
+    @Override
+    public void filter(ContainerRequestContext context) throws IOException {
+        
+        List<JwsSignatureVerifier> theSigVerifiers = getInitializedSigVerifiers();
+        JwsJsonConsumer p = new JwsJsonConsumer(IOUtils.readStringFromStream(context.getEntityStream()));
+        if (!p.verifySignatureWith(theSigVerifiers)) {
+            context.abortWith(JAXRSUtils.toResponse(400));
+            return;
+        }
+        byte[] bytes = p.getDecodedJwsPayloadBytes();
+        context.setEntityStream(new ByteArrayInputStream(bytes));
+        context.getHeaders().putSingle("Content-Length", Integer.toString(bytes.length));
+        
+        // the list is guaranteed to be non-empty
+        JwsJsonSignatureEntry sigEntry = p.getSignatureEntries().get(0);
+        String ct = JoseUtils.checkContentType(sigEntry.getUnionHeader().getContentType(), getDefaultMediaType());
+        if (ct != null) {
+            context.getHeaders().putSingle("Content-Type", ct);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
new file mode 100644
index 0000000..e812e59
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
@@ -0,0 +1,80 @@
+/**
+ * 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.rs.security.jose.jaxrs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+import javax.annotation.Priority;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.WriterInterceptor;
+import javax.ws.rs.ext.WriterInterceptorContext;
+
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.rs.security.jose.JoseConstants;
+import org.apache.cxf.rs.security.jose.JoseHeaders;
+import org.apache.cxf.rs.security.jose.jws.JwsJsonProducer;
+import org.apache.cxf.rs.security.jose.jws.JwsJsonProtectedHeader;
+import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
+
+@Priority(Priorities.JWS_WRITE_PRIORITY)
+public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider implements WriterInterceptor {
+    private boolean contentTypeRequired = true;
+    @Override
+    public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException {
+        
+        List<JwsSignatureProvider> sigProviders = getInitializedSigProviders();
+        OutputStream actualOs = ctx.getOutputStream();
+        CachedOutputStream cos = new CachedOutputStream(); 
+        ctx.setOutputStream(cos);
+        ctx.proceed();
+        JwsJsonProducer p = new JwsJsonProducer(new String(cos.getBytes(), "UTF-8"));
+        for (JwsSignatureProvider signer : sigProviders) {
+            JoseHeaders headers = new JoseHeaders();
+            headers.setAlgorithm(signer.getAlgorithm());
+            setContentTypeIfNeeded(headers, ctx);
+            //TODO: support setting public JWK kid property as the unprotected header;
+            //      the property would have to be associated with the individual signer
+            p.signWith(signer, new JwsJsonProtectedHeader(headers), null);    
+        }
+        ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE_JSON));
+        writeJws(p, actualOs);
+    }
+    
+    public void setContentTypeRequired(boolean contentTypeRequired) {
+        this.contentTypeRequired = contentTypeRequired;
+    }
+    
+    private void setContentTypeIfNeeded(JoseHeaders headers, WriterInterceptorContext ctx) {    
+        if (contentTypeRequired) {
+            MediaType mt = ctx.getMediaType();
+            if (mt != null 
+                && !JAXRSUtils.mediaTypeToString(mt).equals(JoseConstants.MEDIA_TYPE_JOSE_JSON)) {
+                if ("application".equals(mt.getType())) {
+                    headers.setContentType(mt.getSubtype());
+                } else {
+                    headers.setContentType(JAXRSUtils.mediaTypeToString(mt));
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
index ddcaa56..5a42b8d 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
@@ -51,7 +51,7 @@ public class JwsWriterInterceptor extends AbstractJwsWriterProvider implements W
         JoseHeaders headers = new JoseHeaders();
         JwsSignatureProvider sigProvider = getInitializedSigProvider(headers);
         setContentTypeIfNeeded(headers, ctx);
-        ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE_JSON));
+        ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE));
         OutputStream actualOs = ctx.getOutputStream();
         if (useJwsOutputStream) {
             JwsSignature jwsSignature = sigProvider.createJwsSignature(headers);
@@ -88,7 +88,7 @@ public class JwsWriterInterceptor extends AbstractJwsWriterProvider implements W
         if (contentTypeRequired) {
             MediaType mt = ctx.getMediaType();
             if (mt != null 
-                && !JAXRSUtils.mediaTypeToString(mt).equals(JoseConstants.MEDIA_TYPE_JOSE_JSON)) {
+                && !JAXRSUtils.mediaTypeToString(mt).equals(JoseConstants.MEDIA_TYPE_JOSE)) {
                 if ("application".equals(mt.getType())) {
                     headers.setContentType(mt.getSubtype());
                 } else {

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java
index 89ac29d..6c66825 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java
@@ -19,8 +19,11 @@
 
 package org.apache.cxf.rs.security.jose.jwa;
 
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.cxf.rs.security.jose.JoseConstants;
 
@@ -79,6 +82,16 @@ public enum Algorithm {
     public static final String AES_GCM_ALGO_JAVA = "AES/GCM/NoPadding";
     public static final String AES_CBC_ALGO_JAVA = "AES/CBC/PKCS7Padding";
     
+    public static final Set<String> HMAC_SIGN_SET = new HashSet<String>(Arrays.asList(JoseConstants.HMAC_SHA_256_ALGO,
+                                                                        JoseConstants.HMAC_SHA_384_ALGO,
+                                                                        JoseConstants.HMAC_SHA_512_ALGO));
+    public static final Set<String> RSA_SHA_SIGN_SET = new HashSet<String>(Arrays.asList(JoseConstants.RS_SHA_256_ALGO,
+                                                                        JoseConstants.RS_SHA_384_ALGO,
+                                                                        JoseConstants.RS_SHA_512_ALGO));
+    public static final Set<String> EC_SHA_SIGN_SET = new HashSet<String>(Arrays.asList(JoseConstants.ES_SHA_256_ALGO,
+                                                                         JoseConstants.ES_SHA_384_ALGO,
+                                                                         JoseConstants.ES_SHA_512_ALGO));
+    
     private static final Map<String, String> JAVA_TO_JWT_NAMES;
     private static final Map<String, String> JWT_TO_JAVA_NAMES;
     static {
@@ -210,18 +223,13 @@ public enum Algorithm {
             || JoseConstants.A256CBC_HS512_ALGO.equals(algo); 
     }
     public static boolean isHmacSign(String algo) {
-        return JoseConstants.HMAC_SHA_256_ALGO.equals(algo)
-            || JoseConstants.HMAC_SHA_384_ALGO.equals(algo)
-            || JoseConstants.HMAC_SHA_512_ALGO.equals(algo); 
+        return HMAC_SIGN_SET.contains(algo); 
     }
+    
     public static boolean isRsaShaSign(String algo) {
-        return JoseConstants.RS_SHA_256_ALGO.equals(algo)
-            || JoseConstants.RS_SHA_384_ALGO.equals(algo)
-            || JoseConstants.RS_SHA_512_ALGO.equals(algo); 
+        return RSA_SHA_SIGN_SET.contains(algo); 
     }
     public static boolean isEcDsaSign(String algo) {
-        return JoseConstants.ES_SHA_256_ALGO.equals(algo)
-            || JoseConstants.ES_SHA_384_ALGO.equals(algo)
-            || JoseConstants.ES_SHA_512_ALGO.equals(algo); 
+        return EC_SHA_SIGN_SET.contains(algo); 
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
index 483ff52..4158da6 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
@@ -18,13 +18,23 @@
  */
 package org.apache.cxf.rs.security.jose.jwe;
 
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Properties;
+
 import javax.crypto.SecretKey;
 
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.jose.jaxrs.KeyManagementUtils;
 import org.apache.cxf.rs.security.jose.jwa.Algorithm;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
 
 public final class JweUtils {
+    private static final String JSON_WEB_ENCRYPTION_CEK_ALGO_PROP = "rs.security.jwe.content.encryption.algorithm";
+    private static final String JSON_WEB_ENCRYPTION_KEY_ALGO_PROP = "rs.security.jwe.key.encryption.algorithm";
+    private static final String JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP = "rs.security.jwe.zip.algorithm";
     private JweUtils() {
         
     }
@@ -94,4 +104,99 @@ public final class JweUtils {
         }
         return null;
     }
+    public static JweEncryptionProvider loadEncryptionProvider(String propLoc, Message m) {
+        KeyEncryptionAlgorithm keyEncryptionProvider = null;
+        String keyEncryptionAlgo = null;
+        Properties props = null;
+        try {
+            props = ResourceUtils.loadProperties(propLoc, m.getExchange().getBus());
+        } catch (Exception ex) {
+            throw new SecurityException(ex);
+        }
+        
+        String contentEncryptionAlgo = props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP);
+        ContentEncryptionAlgorithm ctEncryptionProvider = null;
+        if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
+            JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_ENCRYPT);
+            keyEncryptionAlgo = getKeyEncryptionAlgo(props, jwk.getAlgorithm());
+            if ("direct".equals(keyEncryptionAlgo)) {
+                contentEncryptionAlgo = getContentEncryptionAlgo(props, jwk.getAlgorithm());
+                ctEncryptionProvider = JweUtils.getContentEncryptionAlgorithm(jwk, contentEncryptionAlgo);
+            } else {
+                keyEncryptionProvider = JweUtils.getKeyEncryptionAlgorithm(jwk, keyEncryptionAlgo);
+            }
+            
+        } else {
+            keyEncryptionProvider = new RSAOaepKeyEncryptionAlgorithm(
+                (RSAPublicKey)KeyManagementUtils.loadPublicKey(m, props), 
+                getKeyEncryptionAlgo(props, keyEncryptionAlgo));
+        }
+        if (keyEncryptionProvider == null && ctEncryptionProvider == null) {
+            throw new SecurityException();
+        }
+        
+        
+        JweHeaders headers = new JweHeaders(getKeyEncryptionAlgo(props, keyEncryptionAlgo), 
+                                            contentEncryptionAlgo);
+        String compression = props.getProperty(JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP);
+        if (compression != null) {
+            headers.setZipAlgorithm(compression);
+        }
+        if (keyEncryptionProvider != null) {
+            if (Algorithm.isAesCbcHmac(contentEncryptionAlgo)) { 
+                return new AesCbcHmacJweEncryption(contentEncryptionAlgo, keyEncryptionProvider);
+            } else {
+                return new WrappedKeyJweEncryption(headers, 
+                                                   keyEncryptionProvider,
+                                                   new AesGcmContentEncryptionAlgorithm(contentEncryptionAlgo));
+            }
+        } else {
+            return new DirectKeyJweEncryption(ctEncryptionProvider);
+        }
+    }
+    public static JweDecryptionProvider loadDecryptionProvider(String propLoc, Message m) {
+        KeyDecryptionAlgorithm keyDecryptionProvider = null;
+        Properties props = null;
+        try {
+            props = ResourceUtils.loadProperties(propLoc, m.getExchange().getBus());
+        } catch (Exception ex) {
+            throw new SecurityException(ex);
+        }    
+        String contentEncryptionAlgo = props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP);
+        SecretKey ctDecryptionKey = null;
+        if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
+            JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_ENCRYPT);
+            String keyEncryptionAlgo = getKeyEncryptionAlgo(props, jwk.getAlgorithm());
+            if ("direct".equals(keyEncryptionAlgo)) {
+                contentEncryptionAlgo = getContentEncryptionAlgo(props, contentEncryptionAlgo);
+                ctDecryptionKey = JweUtils.getContentDecryptionSecretKey(jwk, contentEncryptionAlgo);
+            } else {
+                keyDecryptionProvider = JweUtils.getKeyDecryptionAlgorithm(jwk, keyEncryptionAlgo);
+            }
+        } else {
+            keyDecryptionProvider = new RSAOaepKeyDecryptionAlgorithm(
+                (RSAPrivateKey)KeyManagementUtils.loadPrivateKey(
+                    m, props, KeyManagementUtils.RSSEC_DECRYPT_KEY_PSWD_PROVIDER));
+        }
+        if (keyDecryptionProvider == null && ctDecryptionKey == null) {
+            throw new SecurityException();
+        }
+        if (keyDecryptionProvider != null) {
+            if (Algorithm.isAesCbcHmac(contentEncryptionAlgo)) { 
+                return new AesCbcHmacJweDecryption(keyDecryptionProvider, contentEncryptionAlgo);
+            } else {
+                return new WrappedKeyJweDecryption(keyDecryptionProvider, 
+                                                   new AesGcmContentDecryptionAlgorithm(contentEncryptionAlgo));
+            }
+        } else {
+            return new DirectKeyJweDecryption(ctDecryptionKey, 
+                                              new AesGcmContentDecryptionAlgorithm(contentEncryptionAlgo));
+        }
+    }
+    private static String getKeyEncryptionAlgo(Properties props, String algo) {
+        return algo == null ? props.getProperty(JSON_WEB_ENCRYPTION_KEY_ALGO_PROP) : algo;
+    }
+    private static String getContentEncryptionAlgo(Properties props, String algo) {
+        return algo == null ? props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP) : algo;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
index f22bb89..b44ecc8 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java
@@ -20,10 +20,14 @@ package org.apache.cxf.rs.security.jose.jws;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
+import javax.ws.rs.core.MultivaluedMap;
+
 import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxrs.provider.json.JsonMapObject;
 import org.apache.cxf.jaxrs.provider.json.JsonMapObjectReaderWriter;
 import org.apache.cxf.rs.security.jose.JoseUtils;
@@ -47,26 +51,29 @@ public class JwsJsonConsumer {
     private void prepare() {
         JsonMapObject jsonObject = new JsonMapObject();
         new JsonMapObjectReaderWriter().fromJson(jsonObject, jwsSignedDocument);
-        this.encodedJwsPayload = (String)jsonObject.asMap().get("payload");
+        encodedJwsPayload = (String)jsonObject.asMap().get("payload");
+        if (encodedJwsPayload == null) {
+            throw new SecurityException("Invalid JWS JSON sequence: no payload is available");
+        }
         
-        @SuppressWarnings("unchecked")
-        List<Map<String, Object>> signatureArray = 
-            (List<Map<String, Object>>)jsonObject.asMap().get("signatures");
+        List<Map<String, Object>> signatureArray = CastUtils.cast((List<?>)jsonObject.asMap().get("signatures"));
         
         this.signatureEntries = new ArrayList<JwsJsonSignatureEntry>(signatureArray.size());
         
         for (Map<String, Object> signatureEntry : signatureArray) {
             String protectedHeader = (String)signatureEntry.get("protected");
-            @SuppressWarnings("unchecked")
-            Map<String, Object> header = (Map<String, Object>)signatureEntry.get("header");
+            Map<String, Object> header = CastUtils.cast((Map<?, ?>)signatureEntry.get("header"));
             String signature = (String)signatureEntry.get("signature");
             JwsJsonSignatureEntry signatureObject = 
                 new JwsJsonSignatureEntry(encodedJwsPayload, 
                                           protectedHeader, 
                                           signature, 
-                                          new JwsJsonUnprotectedHeader(header));
+                                          header != null ? new JwsJsonUnprotectedHeader(header) : null);
             this.signatureEntries.add(signatureObject);
         }
+        if (signatureEntries.isEmpty()) {
+            throw new SecurityException("Invalid JWS JSON sequence: no signatures are available");
+        }
     }
     public String getSignedDocument() {
         return this.jwsSignedDocument;
@@ -83,6 +90,9 @@ public class JwsJsonConsumer {
     public List<JwsJsonSignatureEntry> getSignatureEntries() {
         return Collections.unmodifiableList(signatureEntries);
     }
+    public MultivaluedMap<String, JwsJsonSignatureEntry> getSignatureEntryMap() {
+        return JwsUtils.getJwsJsonSignatureMap(signatureEntries);
+    }
     public boolean verifySignatureWith(JwsSignatureVerifier validator) {
         for (JwsJsonSignatureEntry signatureEntry : signatureEntries) {
             if (signatureEntry.verifySignatureWith(validator)) {
@@ -91,6 +101,45 @@ public class JwsJsonConsumer {
         }
         return false;
     }
+    public boolean verifySignatureWith(List<JwsSignatureVerifier> validators) {
+        try {
+            verifyAndGetNonValidated(validators);
+            return true;
+        } catch (SecurityException ex) {
+            return false;
+        }
+    }
+    public List<JwsJsonSignatureEntry> verifyAndGetNonValidated(List<JwsSignatureVerifier> validators) {
+        if (validators.size() > signatureEntries.size()) {
+            throw new SecurityException("Too many signature validators");
+        }
+        // TODO: more effective approach is needed
+        List<JwsJsonSignatureEntry> validatedSignatures = new LinkedList<JwsJsonSignatureEntry>();
+        for (JwsSignatureVerifier validator : validators) {
+            boolean validated = false;
+            for (JwsJsonSignatureEntry sigEntry : signatureEntries) {
+                if (sigEntry.verifySignatureWith(validator)) {     
+                    validatedSignatures.add(sigEntry);
+                    validated = true;
+                    break;
+                }
+            }
+            if (!validated) {
+                throw new SecurityException();
+            }
+        }
+        if (validatedSignatures.isEmpty()) {
+            throw new SecurityException();
+        }
+        List<JwsJsonSignatureEntry> nonValidatedSignatures = new LinkedList<JwsJsonSignatureEntry>();
+        for (JwsJsonSignatureEntry sigEntry : signatureEntries) {
+            if (!validatedSignatures.contains(sigEntry)) {        
+                nonValidatedSignatures.add(sigEntry);
+            }
+        }
+        return nonValidatedSignatures;
+    }
+    
     public boolean verifySignatureWith(JsonWebKey key) {
         return verifySignatureWith(JwsUtils.getSignatureVerifier(key));
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
index 740ded1..b43dc40 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonProducer.java
@@ -22,6 +22,8 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
+import javax.ws.rs.core.MultivaluedMap;
+
 import org.apache.cxf.common.util.Base64UrlUtility;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.rs.security.jose.JoseHeaders;
@@ -58,6 +60,15 @@ public class JwsJsonProducer {
     public List<JwsJsonSignatureEntry> getSignatureEntries() {
         return Collections.unmodifiableList(signatures);
     }
+    public MultivaluedMap<String, JwsJsonSignatureEntry> getSignatureEntryMap() {
+        return JwsUtils.getJwsJsonSignatureMap(signatures);
+    }
+    public String signWith(List<JwsSignatureProvider> signers) {
+        for (JwsSignatureProvider signer : signers) {
+            signWith(signer);    
+        }
+        return getJwsJsonSignedDocument(); 
+    }
     public String signWith(JwsSignatureProvider signer) {
         JoseHeaders headers = new JoseHeaders();
         headers.setAlgorithm(signer.getAlgorithm());

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
index b9f37b5..a430575 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonSignatureEntry.java
@@ -95,6 +95,9 @@ public class JwsJsonSignatureEntry {
     public String getUnsignedEncodedSequence() {
         return getEncodedProtectedHeader() + "." + getEncodedJwsPayload();
     }
+    public String getKeyId() {
+        return getUnionHeader().getKeyId();
+    }
     public boolean verifySignatureWith(JwsSignatureVerifier validator) {
         try {
             return validator.verify(getUnionHeader(),

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
index 08c59c1..30e3b8c 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
@@ -18,11 +18,23 @@
  */
 package org.apache.cxf.rs.security.jose.jws;
 
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.List;
+import java.util.Properties;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.jose.jaxrs.KeyManagementUtils;
 import org.apache.cxf.rs.security.jose.jwa.Algorithm;
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
 
 public final class JwsUtils {
+    private static final String JSON_WEB_SIGNATURE_ALGO_PROP = "rs.security.jws.content.signature.algorithm";
     private JwsUtils() {
         
     }
@@ -63,5 +75,59 @@ public final class JwsUtils {
         }
         return theVerifier;
     }
-    
+    public static MultivaluedMap<String, JwsJsonSignatureEntry> getJwsJsonSignatureMap(
+        List<JwsJsonSignatureEntry> signatures) {
+        MultivaluedMap<String, JwsJsonSignatureEntry> map = new MetadataMap<String, JwsJsonSignatureEntry>();
+        for (JwsJsonSignatureEntry entry : signatures) {
+            map.add(entry.getUnionHeader().getAlgorithm(), entry);
+        }
+        return map;
+    }
+    public static JwsSignatureProvider loadSignatureProvider(String propLoc, Message m) {
+        Properties props = null;
+        try {
+            props = ResourceUtils.loadProperties(propLoc, m.getExchange().getBus());
+        } catch (Exception ex) {
+            throw new SecurityException(ex);
+        }
+        JwsSignatureProvider theSigProvider = null; 
+        String rsaSignatureAlgo = null;
+        if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
+            JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_SIGN);
+            rsaSignatureAlgo = getSignatureAlgo(props, jwk.getAlgorithm());
+            theSigProvider = JwsUtils.getSignatureProvider(jwk, rsaSignatureAlgo);
+        } else {
+            rsaSignatureAlgo = getSignatureAlgo(props, null);
+            RSAPrivateKey pk = (RSAPrivateKey)KeyManagementUtils.loadPrivateKey(m, props, 
+                KeyManagementUtils.RSSEC_SIG_KEY_PSWD_PROVIDER);
+            theSigProvider = new PrivateKeyJwsSignatureProvider(pk, rsaSignatureAlgo);
+        }
+        if (theSigProvider == null) {
+            throw new SecurityException();
+        }
+        return theSigProvider;
+    }
+    public static JwsSignatureVerifier loadSignatureVerifier(String propLoc, Message m) {
+        Properties props = null;
+        try {
+            props = ResourceUtils.loadProperties(propLoc, m.getExchange().getBus());
+        } catch (Exception ex) {
+            throw new SecurityException(ex);
+        }
+        JwsSignatureVerifier theVerifier = null;
+        String rsaSignatureAlgo = null;
+        if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
+            JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_VERIFY);
+            rsaSignatureAlgo = getSignatureAlgo(props, jwk.getAlgorithm());
+            theVerifier = JwsUtils.getSignatureVerifier(jwk, rsaSignatureAlgo);
+            
+        } else {
+            theVerifier = new PublicKeyJwsSignatureVerifier(
+                              (RSAPublicKey)KeyManagementUtils.loadPublicKey(m, props));
+        }
+        return theVerifier;
+    }
+    private static String getSignatureAlgo(Properties props, String algo) {
+        return algo == null ? props.getProperty(JSON_WEB_SIGNATURE_ALGO_PROP) : algo;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
index a79754a..e46b5cd 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumerTest.java
@@ -59,13 +59,13 @@ public class JwsJsonConsumerTest extends Assert {
         List<JwsJsonSignatureEntry> sigEntries = consumer.getSignatureEntries();
         assertEquals(2, sigEntries.size());
         // 1st signature
-        String firstKid = (String)sigEntries.get(0).getUnionHeader().getHeader("kid");
+        String firstKid = (String)sigEntries.get(0).getKeyId();
         assertEquals(KID_OF_THE_FIRST_SIGNER, firstKid);
         JsonWebKey rsaKey = jwks.getKey(firstKid);
         assertNotNull(rsaKey);
         assertTrue(sigEntries.get(0).verifySignatureWith(rsaKey));
         // 2nd signature
-        String secondKid = (String)sigEntries.get(1).getUnionHeader().getHeader("kid");
+        String secondKid = (String)sigEntries.get(1).getKeyId();
         assertEquals(KID_OF_THE_SECOND_SIGNER, secondKid);
         JsonWebKey ecKey = jwks.getKey(secondKid);
         assertNotNull(ecKey);

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/BookServerJwsJson.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/BookServerJwsJson.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/BookServerJwsJson.java
new file mode 100644
index 0000000..3b451e1
--- /dev/null
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/BookServerJwsJson.java
@@ -0,0 +1,57 @@
+/**
+ * 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.jwt;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.cxf.testutil.common.TestUtil;
+    
+public class BookServerJwsJson extends AbstractBusTestServerBase {
+    public static final String PORT = TestUtil.getPortNumber("jaxrs-jws-json");
+    private static final String SERVER_CONFIG_FILE =
+        "org/apache/cxf/systest/jaxrs/security/jwt/serverJwsJson.xml";
+    
+    protected void run() {
+        SpringBusFactory bf = new SpringBusFactory();
+        Bus springBus = bf.createBus(SERVER_CONFIG_FILE);
+        BusFactory.setDefaultBus(springBus);
+        setBus(springBus);
+        
+        try {
+            new BookServerJwsJson();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }        
+    }
+
+    public static void main(String[] args) {
+        try {
+            BookServerJwsJson s = new BookServerJwsJson();
+            s.start();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            System.exit(-1);
+        } finally {
+            System.out.println("done!");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJwsJsonTest.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJwsJsonTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJwsJsonTest.java
new file mode 100644
index 0000000..892ca40
--- /dev/null
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJwsJsonTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.jwt;
+
+import java.net.URL;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.rs.security.jose.jaxrs.JwsJsonClientResponseFilter;
+import org.apache.cxf.rs.security.jose.jaxrs.JwsJsonWriterInterceptor;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class JAXRSJwsJsonTest extends AbstractBusClientServerTestBase {
+    public static final String PORT = BookServerJwsJson.PORT;
+    
+    @BeforeClass
+    public static void startServers() throws Exception {
+        assertTrue("server did not launch correctly", 
+                   launchServer(BookServerJwsJson.class, true));
+    }
+    
+    @Test
+    public void testJwsJwkHMac() throws Exception {
+        String address = "https://localhost:" + PORT + "/jwsjsonhmac";
+        JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = JAXRSJwsJsonTest.class.getResource("client.xml");
+        Bus springBus = bf.createBus(busFile.toString());
+        bean.setBus(springBus);
+        bean.setServiceClass(BookStore.class);
+        bean.setAddress(address);
+        List<Object> providers = new LinkedList<Object>();
+        providers.add(new JwsJsonWriterInterceptor());
+        providers.add(new JwsJsonClientResponseFilter());
+        bean.setProviders(providers);
+        bean.getProperties(true).put("rs.security.signature.list.properties", 
+                                     "org/apache/cxf/systest/jaxrs/security/secret.jwk.properties");
+        BookStore bs = bean.create(BookStore.class);
+        String text = bs.echoText("book");
+        assertEquals("book", text);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/1858ea6b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/serverJwsJson.xml
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/serverJwsJson.xml b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/serverJwsJson.xml
new file mode 100644
index 0000000..2e3911d
--- /dev/null
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/serverJwsJson.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<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         ">
+    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
+    <cxf:bus>
+        <cxf:features>
+            <cxf:logging/>
+        </cxf:features>
+    </cxf:bus>
+    <httpj:engine-factory id="port-9095-tls-config">
+        <httpj:engine port="${testutil.ports.jaxrs-jws-json}">
+            <httpj:tlsServerParameters>
+                <sec:keyManagers keyPassword="password">
+                    <sec:keyStore type="JKS" password="password" file="src/test/java/org/apache/cxf/systest/http/resources/Bethal.jks"/>
+                </sec:keyManagers>
+                <sec:trustManagers>
+                    <sec:keyStore type="JKS" password="password" file="src/test/java/org/apache/cxf/systest/http/resources/Truststore.jks"/>
+                </sec:trustManagers>
+                <sec:cipherSuitesFilter>
+                    <sec:include>.*_EXPORT_.*</sec:include>
+                    <sec:include>.*_EXPORT1024_.*</sec:include>
+                    <sec:include>.*_WITH_AES_.*</sec:include>
+                </sec:cipherSuitesFilter>
+                <sec:clientAuthentication want="true" required="true"/>
+            </httpj:tlsServerParameters>
+        </httpj:engine>
+    </httpj:engine-factory>
+    
+    <bean id="serviceBean" class="org.apache.cxf.systest.jaxrs.security.jwt.BookStore"/>
+    <bean id="jwsInFilter" class="org.apache.cxf.rs.security.jose.jaxrs.JwsJsonContainerRequestFilter"/>
+    <bean id="jwsOutFilter" class="org.apache.cxf.rs.security.jose.jaxrs.JwsJsonWriterInterceptor"/>
+    <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-jws-json}/jwsjsonhmac">
+        <jaxrs:serviceBeans>
+            <ref bean="serviceBean"/>
+        </jaxrs:serviceBeans>
+        <jaxrs:providers>
+            <ref bean="jwsInFilter"/>
+            <ref bean="jwsOutFilter"/>
+        </jaxrs:providers>
+        <jaxrs:properties>
+            <entry key="rs.security.signature.list.properties" value="org/apache/cxf/systest/jaxrs/security/secret.jwk.properties"/>
+        </jaxrs:properties>
+    </jaxrs:server>
+    
+</beans>