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>