Repository: cxf
Updated Branches:
  refs/heads/master ad7c861a8 -> eb14ce920


[CXF-7366] Adding a negative test, updating JWE filters too


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

Branch: refs/heads/master
Commit: eb14ce9206bc43371f149f9d0b1c6e8e2682e5c0
Parents: ad7c861
Author: Sergey Beryozkin <sberyoz...@gmail.com>
Authored: Thu May 11 11:38:18 2017 +0100
Committer: Sergey Beryozkin <sberyoz...@gmail.com>
Committed: Thu May 11 11:38:18 2017 +0100

----------------------------------------------------------------------
 .../jose/jaxrs/AbstractJweDecryptingFilter.java | 20 +++++
 .../jaxrs/AbstractJweJsonDecryptingFilter.java  | 20 +++++
 .../jaxrs/AbstractJwsJsonReaderProvider.java    | 32 +------
 .../jose/jaxrs/AbstractJwsReaderProvider.java   | 35 +-------
 .../rs/security/jose/jaxrs/JoseJaxrsUtils.java  | 95 ++++++++++++++++++++
 .../jose/jaxrs/JweClientResponseFilter.java     |  5 +-
 .../jose/jaxrs/JweContainerRequestFilter.java   |  3 +
 .../jose/jaxrs/JweJsonClientResponseFilter.java |  3 +
 .../jaxrs/JweJsonContainerRequestFilter.java    |  3 +
 .../jose/jaxrs/JweJsonWriterInterceptor.java    | 19 ++++
 .../jose/jaxrs/JweWriterInterceptor.java        | 21 ++++-
 .../jose/jaxrs/JwsJsonWriterInterceptor.java    | 22 +----
 .../jose/jaxrs/JwsWriterInterceptor.java        | 16 +---
 .../systest/jaxrs/security/jose/BookStore.java  |  2 +-
 .../jose/jwejws/HttpHeaderModifyingFilter.java  | 42 +++++++++
 .../security/jose/jwejws/JAXRSJweJwsTest.java   |  9 ++
 .../jaxrs/security/jose/jwejws/server.xml       |  2 +
 17 files changed, 256 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
index 2ee9d2d..c6d704a 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java
@@ -21,6 +21,9 @@ package org.apache.cxf.rs.security.jose.jaxrs;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.util.Set;
+
+import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.rs.security.jose.common.JoseUtils;
@@ -31,6 +34,8 @@ import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
 import org.apache.cxf.rs.security.jose.jwe.JweUtils;
 
 public class AbstractJweDecryptingFilter {
+    private Set<String> protectedHttpHeaders;
+    private boolean validateHttpHeaders;
     private JweDecryptionProvider decryption;
     private String defaultMediaType;
     protected JweDecryptionOutput decrypt(InputStream is) throws IOException {
@@ -63,4 +68,19 @@ public class AbstractJweDecryptingFilter {
         this.defaultMediaType = defaultMediaType;
     }
 
+    public void setValidateHttpHeaders(boolean validateHttpHeaders) {
+        this.validateHttpHeaders = validateHttpHeaders;
+    }
+    public boolean isValidateHttpHeaders() {
+        return validateHttpHeaders;
+    }
+    
+    protected void validateHttpHeadersIfNeeded(MultivaluedMap<String, String> 
httpHeaders, JweHeaders jweHeaders) {
+        JoseJaxrsUtils.validateHttpHeaders(httpHeaders, 
+                                           jweHeaders, 
+                                           protectedHttpHeaders);
+    }
+    public void setProtectedHttpHeaders(Set<String> protectedHttpHeaders) {
+        this.protectedHttpHeaders = protectedHttpHeaders;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonDecryptingFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonDecryptingFilter.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonDecryptingFilter.java
index 97ee5d9..bddbf65 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonDecryptingFilter.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonDecryptingFilter.java
@@ -22,6 +22,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
@@ -34,6 +37,8 @@ import 
org.apache.cxf.rs.security.jose.jwe.JweJsonEncryptionEntry;
 import org.apache.cxf.rs.security.jose.jwe.JweUtils;
 
 public class AbstractJweJsonDecryptingFilter {
+    private Set<String> protectedHttpHeaders;
+    private boolean validateHttpHeaders;
     private JweDecryptionProvider decryption;
     private String defaultMediaType;
     private Map<String, Object> recipientProperties;
@@ -76,4 +81,19 @@ public class AbstractJweJsonDecryptingFilter {
         this.recipientProperties = recipientProperties;
     }
 
+    public void setValidateHttpHeaders(boolean validateHttpHeaders) {
+        this.validateHttpHeaders = validateHttpHeaders;
+    }
+    public boolean isValidateHttpHeaders() {
+        return validateHttpHeaders;
+    }
+    
+    protected void validateHttpHeadersIfNeeded(MultivaluedMap<String, String> 
httpHeaders, JweHeaders jweHeaders) {
+        JoseJaxrsUtils.validateHttpHeaders(httpHeaders, 
+                                           jweHeaders, 
+                                           protectedHttpHeaders);
+    }
+    public void setProtectedHttpHeaders(Set<String> protectedHttpHeaders) {
+        this.protectedHttpHeaders = protectedHttpHeaders;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
index c772714..004e21c 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonReaderProvider.java
@@ -18,16 +18,12 @@
  */
 package org.apache.cxf.rs.security.jose.jaxrs;
 
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.logging.Logger;
 
-import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.common.logging.LogUtils;
@@ -41,9 +37,7 @@ import org.apache.cxf.rs.security.jose.jws.JwsUtils;
 
 public class AbstractJwsJsonReaderProvider {
     protected static final Logger LOG = 
LogUtils.getL7dLogger(AbstractJwsJsonReaderProvider.class);
-    private static final Set<String> DEFAULT_PROTECTED_HTTP_HEADERS = 
-        new HashSet<String>(Arrays.asList(HttpHeaders.CONTENT_TYPE, 
HttpHeaders.ACCEPT));
-    private Set<String> protectedHttpHeaders = DEFAULT_PROTECTED_HTTP_HEADERS;
+    private Set<String> protectedHttpHeaders;
     private boolean validateHttpHeaders;
     private JwsSignatureVerifier sigVerifier;
     private String defaultMediaType;
@@ -95,27 +89,9 @@ public class AbstractJwsJsonReaderProvider {
     }
     
     protected void validateHttpHeadersIfNeeded(MultivaluedMap<String, String> 
httpHeaders, JwsHeaders jwsHeaders) {
-        Map<String, String> jwsHttpHeaders = new HashMap<String, String>();
-        Map<String, String> updatedHttpHeaders = new HashMap<String, String>();
-        final String prefix = "http.";
-        for (String headerName : protectedHttpHeaders) {
-            List<String> headerValues = httpHeaders.get(headerName);
-            if (headerValues != null) {
-                String headerValue = headerValues.size() > 1 ? 
headerValues.toString()
-                    : headerValues.get(0).toString();
-                String prefixedHeaderName = prefix + headerName;
-                updatedHttpHeaders.put(prefixedHeaderName, headerValue);
-                String jwsHeaderValue = 
jwsHeaders.getStringProperty(prefixedHeaderName);
-                if (jwsHeaderValue != null) {
-                    jwsHttpHeaders.put(prefixedHeaderName, jwsHeaderValue);
-                }    
-            }
-            
-        }
-        if (jwsHttpHeaders.size() != updatedHttpHeaders.size() 
-            || 
!jwsHttpHeaders.entrySet().containsAll(updatedHttpHeaders.entrySet())) { 
-            throw new JwsException(JwsException.Error.INVALID_SIGNATURE);
-        }
+        JoseJaxrsUtils.validateHttpHeaders(httpHeaders, 
+                                           jwsHeaders, 
+                                           protectedHttpHeaders);
     }
     public void setProtectedHttpHeaders(Set<String> protectedHttpHeaders) {
         this.protectedHttpHeaders = protectedHttpHeaders;

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
index 1780574..7a13f96 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java
@@ -18,26 +18,17 @@
  */
 package org.apache.cxf.rs.security.jose.jaxrs;
 
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
-import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.rs.security.jose.common.JoseUtils;
-import org.apache.cxf.rs.security.jose.jws.JwsException;
 import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
 import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier;
 import org.apache.cxf.rs.security.jose.jws.JwsUtils;
 
 public class AbstractJwsReaderProvider {
-    private static final Set<String> DEFAULT_PROTECTED_HTTP_HEADERS = 
-        new HashSet<String>(Arrays.asList(HttpHeaders.CONTENT_TYPE, 
HttpHeaders.ACCEPT));
-    private Set<String> protectedHttpHeaders = DEFAULT_PROTECTED_HTTP_HEADERS;
+    private Set<String> protectedHttpHeaders;
     private boolean validateHttpHeaders;
     
     private JwsSignatureVerifier sigVerifier;
@@ -71,27 +62,9 @@ public class AbstractJwsReaderProvider {
     }
     
     protected void validateHttpHeadersIfNeeded(MultivaluedMap<String, String> 
httpHeaders, JwsHeaders jwsHeaders) {
-        Map<String, String> jwsHttpHeaders = new HashMap<String, String>();
-        Map<String, String> updatedHttpHeaders = new HashMap<String, String>();
-        final String prefix = "http.";
-        for (String headerName : protectedHttpHeaders) {
-            List<String> headerValues = httpHeaders.get(headerName);
-            if (headerValues != null) {
-                String headerValue = headerValues.size() > 1 ? 
headerValues.toString()
-                    : headerValues.get(0).toString();
-                String prefixedHeaderName = prefix + headerName;
-                updatedHttpHeaders.put(prefixedHeaderName, headerValue);
-                String jwsHeaderValue = 
jwsHeaders.getStringProperty(prefixedHeaderName);
-                if (jwsHeaderValue != null) {
-                    jwsHttpHeaders.put(prefixedHeaderName, jwsHeaderValue);
-                }    
-            }
-            
-        }
-        if (jwsHttpHeaders.size() != updatedHttpHeaders.size() 
-            || 
!jwsHttpHeaders.entrySet().containsAll(updatedHttpHeaders.entrySet())) { 
-            throw new JwsException(JwsException.Error.INVALID_SIGNATURE);
-        }
+        JoseJaxrsUtils.validateHttpHeaders(httpHeaders, 
+                                           jwsHeaders, 
+                                           protectedHttpHeaders);
     }
     public void setProtectedHttpHeaders(Set<String> protectedHttpHeaders) {
         this.protectedHttpHeaders = protectedHttpHeaders;

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JoseJaxrsUtils.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JoseJaxrsUtils.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JoseJaxrsUtils.java
new file mode 100644
index 0000000..b1f1a38
--- /dev/null
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JoseJaxrsUtils.java
@@ -0,0 +1,95 @@
+/**
+ * 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.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.rs.security.jose.common.JoseHeaders;
+
+public final class JoseJaxrsUtils {
+    private static final String HTTP_PREFIX = "http.";
+    private static final Set<String> DEFAULT_PROTECTED_HTTP_HEADERS = 
+        new HashSet<String>(Arrays.asList(HttpHeaders.CONTENT_TYPE, 
HttpHeaders.ACCEPT));
+    
+    private JoseJaxrsUtils() {
+
+    }
+    
+    public static void protectHttpHeaders(MultivaluedMap<String, Object> 
httpHeaders,
+                                          JoseHeaders joseHeaders,
+                                          Set<String> protectedHttpHeaders) {
+        if (protectedHttpHeaders == null) {
+            protectedHttpHeaders = DEFAULT_PROTECTED_HTTP_HEADERS;
+        }
+        for (String headerName : protectedHttpHeaders) {
+            List<Object> headerValues = httpHeaders.get(headerName);
+            if (headerValues != null) {
+                String joseHeaderValue = getJoseHeaderValue(headerValues);
+                String prefixedHeaderName = HTTP_PREFIX + headerName;
+                joseHeaders.setHeader(prefixedHeaderName, joseHeaderValue);
+            }
+        }
+    }
+    private static String getJoseHeaderValue(List<? extends Object> 
headerValues) {
+        StringBuilder sb = new StringBuilder(); 
+        for (Object o : headerValues) {
+            String[] parts = o.toString().split(",");
+            for (String part : parts) {
+                sb.append(part);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static void validateHttpHeaders(MultivaluedMap<String, String> 
httpHeaders, 
+                                           JoseHeaders joseHeaders,
+                                           Set<String> protectedHttpHeaders) {
+        if (protectedHttpHeaders == null) {
+            protectedHttpHeaders = DEFAULT_PROTECTED_HTTP_HEADERS;
+        }
+        Map<String, String> joseHttpHeaders = new HashMap<String, String>();
+        Map<String, String> updatedHttpHeaders = new HashMap<String, String>();
+        for (String headerName : protectedHttpHeaders) {
+            List<String> headerValues = httpHeaders.get(headerName);
+            if (headerValues != null) {
+                String headerValue = getJoseHeaderValue(headerValues);
+                String prefixedHeaderName = HTTP_PREFIX + headerName;
+                updatedHttpHeaders.put(prefixedHeaderName, headerValue);
+                String joseHeaderValue = 
joseHeaders.getStringProperty(prefixedHeaderName);
+                if (joseHeaderValue != null) {
+                    joseHttpHeaders.put(prefixedHeaderName, joseHeaderValue);
+                }    
+            }
+            
+        }
+        if (joseHttpHeaders.size() != updatedHttpHeaders.size() 
+            || 
!joseHttpHeaders.entrySet().containsAll(updatedHttpHeaders.entrySet())) { 
+            throw ExceptionUtils.toBadRequestException(null, null);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java
index 176973b..4b02790 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java
@@ -41,6 +41,9 @@ public class JweClientResponseFilter extends 
AbstractJweDecryptingFilter impleme
         if (ct != null) {
             res.getHeaders().putSingle("Content-Type", ct);
         }
+        if (super.isValidateHttpHeaders()) {
+            super.validateHttpHeadersIfNeeded(res.getHeaders(), 
out.getHeaders());
+        }
     }
-
+    
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java
index 9f0d831..d22cc79 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java
@@ -46,5 +46,8 @@ public class JweContainerRequestFilter extends 
AbstractJweDecryptingFilter imple
         if (ct != null) {
             context.getHeaders().putSingle("Content-Type", ct);
         }
+        if (super.isValidateHttpHeaders()) {
+            super.validateHttpHeadersIfNeeded(context.getHeaders(), 
out.getHeaders());
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonClientResponseFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonClientResponseFilter.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonClientResponseFilter.java
index cb48b95..8503a70 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonClientResponseFilter.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonClientResponseFilter.java
@@ -41,6 +41,9 @@ public class JweJsonClientResponseFilter extends 
AbstractJweJsonDecryptingFilter
         if (ct != null) {
             res.getHeaders().putSingle("Content-Type", ct);
         }
+        if (super.isValidateHttpHeaders()) {
+            super.validateHttpHeadersIfNeeded(res.getHeaders(), 
out.getHeaders());
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonContainerRequestFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonContainerRequestFilter.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonContainerRequestFilter.java
index d0bb31f..5980b77 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonContainerRequestFilter.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonContainerRequestFilter.java
@@ -49,6 +49,9 @@ public class JweJsonContainerRequestFilter extends 
AbstractJweJsonDecryptingFilt
             if (ct != null) {
                 context.getHeaders().putSingle("Content-Type", ct);
             }
+            if (super.isValidateHttpHeaders()) {
+                super.validateHttpHeadersIfNeeded(context.getHeaders(), 
out.getHeaders());
+            }
         } catch (JweException ex) {
             context.abortWith(JAXRSUtils.toResponse(400));
             return;

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
index d373678..9d0926f 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 import javax.annotation.Priority;
 import javax.ws.rs.WebApplicationException;
@@ -43,6 +44,8 @@ import org.apache.cxf.rs.security.jose.jwe.JweJsonProducer;
 
 @Priority(Priorities.JWE_WRITE_PRIORITY)
 public class JweJsonWriterInterceptor extends AbstractJweJsonWriterProvider 
implements WriterInterceptor {
+    private Set<String> protectedHttpHeaders;
+    private boolean protectHttpHeaders;
     private boolean contentTypeRequired = true;
     private boolean useJweOutputStream;
     @Override
@@ -67,6 +70,7 @@ public class JweJsonWriterInterceptor extends 
AbstractJweJsonWriterProvider impl
         if (ctString != null) {
             protectedHeaders.setContentType(ctString);
         }
+        protectHttpHeadersIfNeeded(ctx, protectedHeaders);
         List<KeyAlgorithm> keyAlgos = new ArrayList<>();
         for (JweEncryptionProvider p : providers) {
             if (!keyAlgos.contains(p.getKeyAlgorithm())) {
@@ -114,6 +118,21 @@ public class JweJsonWriterInterceptor extends 
AbstractJweJsonWriterProvider impl
         this.useJweOutputStream = useJweOutputStream;
     }
 
+    protected void protectHttpHeadersIfNeeded(WriterInterceptorContext ctx, 
JweHeaders jweHeaders) {
+        if (protectHttpHeaders) {
+            JoseJaxrsUtils.protectHttpHeaders(ctx.getHeaders(), 
+                                              jweHeaders, 
+                                              protectedHttpHeaders);
+        }
+        
+    }
 
+    public void setProtectHttpHeaders(boolean protectHttpHeaders) {
+        this.protectHttpHeaders = protectHttpHeaders;
+    }
+
+    public void setProtectedHttpHeaders(Set<String> protectedHttpHeaders) {
+        this.protectedHttpHeaders = protectedHttpHeaders;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
index bac479f..9fb92ff 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java
@@ -21,6 +21,7 @@ package org.apache.cxf.rs.security.jose.jaxrs;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Set;
 import java.util.logging.Logger;
 import java.util.zip.DeflaterOutputStream;
 
@@ -49,6 +50,8 @@ import org.apache.cxf.rs.security.jose.jwe.JweUtils;
 @Priority(Priorities.JWE_WRITE_PRIORITY)
 public class JweWriterInterceptor implements WriterInterceptor {
     protected static final Logger LOG = 
LogUtils.getL7dLogger(JweWriterInterceptor.class);
+    private Set<String> protectedHttpHeaders;
+    private boolean protectHttpHeaders;
     private JweEncryptionProvider encryptionProvider;
     private boolean contentTypeRequired = true;
     private boolean useJweOutputStream;
@@ -74,7 +77,7 @@ public class JweWriterInterceptor implements 
WriterInterceptor {
         if (ctString != null) {
             jweHeaders.setContentType(ctString);
         }
-
+        protectHttpHeadersIfNeeded(ctx, jweHeaders);
         if (useJweOutputStream) {
             JweEncryptionOutput encryption =
                 theEncryptionProvider.getEncryptionOutput(new 
JweEncryptionInput(jweHeaders));
@@ -133,4 +136,20 @@ public class JweWriterInterceptor implements 
WriterInterceptor {
         this.encryptionProvider = encryptionProvider;
     }
 
+    protected void protectHttpHeadersIfNeeded(WriterInterceptorContext ctx, 
JweHeaders jweHeaders) {
+        if (protectHttpHeaders) {
+            JoseJaxrsUtils.protectHttpHeaders(ctx.getHeaders(), 
+                                              jweHeaders, 
+                                              protectedHttpHeaders);
+        }
+        
+    }
+
+    public void setProtectHttpHeaders(boolean protectHttpHeaders) {
+        this.protectHttpHeaders = protectHttpHeaders;
+    }
+
+    public void setProtectedHttpHeaders(Set<String> protectedHttpHeaders) {
+        this.protectedHttpHeaders = protectedHttpHeaders;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
index 0f3bebe..6aca136 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
@@ -22,16 +22,12 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import javax.annotation.Priority;
 import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.WriterInterceptor;
 import javax.ws.rs.ext.WriterInterceptorContext;
 
@@ -51,9 +47,7 @@ import 
org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
 
 @Priority(Priorities.JWS_WRITE_PRIORITY)
 public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider 
implements WriterInterceptor {
-    private static final Set<String> DEFAULT_PROTECTED_HTTP_HEADERS = 
-        new HashSet<String>(Arrays.asList(HttpHeaders.CONTENT_TYPE, 
HttpHeaders.ACCEPT));
-    private Set<String> protectedHttpHeaders = DEFAULT_PROTECTED_HTTP_HEADERS;
+    private Set<String> protectedHttpHeaders;
     private boolean protectHttpHeaders;
     private JsonMapObjectReaderWriter writer = new JsonMapObjectReaderWriter();
     private boolean contentTypeRequired = true;
@@ -148,17 +142,9 @@ public class JwsJsonWriterInterceptor extends 
AbstractJwsJsonWriterProvider impl
     
     protected void protectHttpHeadersIfNeeded(WriterInterceptorContext ctx, 
JwsHeaders jwsHeaders) {
         if (protectHttpHeaders) {
-            final String prefix = "http.";
-            MultivaluedMap<String, Object> httpHeaders = ctx.getHeaders(); 
-            for (String headerName : protectedHttpHeaders) {
-                List<Object> headerValues = httpHeaders.get(headerName);
-                if (headerValues != null) {
-                    String jwsHeaderValue = headerValues.size() > 1 ? 
headerValues.toString()
-                        : headerValues.get(0).toString();
-                    String prefixedHeaderName = prefix + headerName;
-                    jwsHeaders.setHeader(prefixedHeaderName, jwsHeaderValue);
-                }
-            }
+            JoseJaxrsUtils.protectHttpHeaders(ctx.getHeaders(), 
+                                              jwsHeaders, 
+                                              protectedHttpHeaders);
         }
         
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
index 75c655e..7f8664f 100644
--- 
a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
+++ 
b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java
@@ -23,14 +23,12 @@ import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import javax.annotation.Priority;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.ext.WriterInterceptor;
 import javax.ws.rs.ext.WriterInterceptorContext;
 
@@ -136,17 +134,9 @@ public class JwsWriterInterceptor extends 
AbstractJwsWriterProvider implements W
     }
     protected void protectHttpHeadersIfNeeded(WriterInterceptorContext ctx, 
JwsHeaders jwsHeaders) {
         if (protectHttpHeaders) {
-            final String prefix = "http.";
-            MultivaluedMap<String, Object> httpHeaders = ctx.getHeaders(); 
-            for (String headerName : protectedHttpHeaders) {
-                List<Object> headerValues = httpHeaders.get(headerName);
-                if (headerValues != null) {
-                    String jwsHeaderValue = headerValues.size() > 1 ? 
headerValues.toString()
-                        : headerValues.get(0).toString();
-                    String prefixedHeaderName = prefix + headerName;
-                    jwsHeaders.setHeader(prefixedHeaderName, jwsHeaderValue);
-                }
-            }
+            JoseJaxrsUtils.protectHttpHeaders(ctx.getHeaders(), 
+                                              jwsHeaders, 
+                                              protectedHttpHeaders);
         }
         
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
----------------------------------------------------------------------
diff --git 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
index 518720e..cc5fcdc 100644
--- 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
+++ 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
@@ -38,7 +38,7 @@ public class BookStore {
 
     @POST
     @Path("/books")
-    @Produces("text/plain")
+    @Produces({"text/plain", "application/json"})
     @Consumes("text/plain")
     public String echoText(String text) {
         return text;

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/HttpHeaderModifyingFilter.java
----------------------------------------------------------------------
diff --git 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/HttpHeaderModifyingFilter.java
 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/HttpHeaderModifyingFilter.java
new file mode 100644
index 0000000..d04bc65
--- /dev/null
+++ 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/HttpHeaderModifyingFilter.java
@@ -0,0 +1,42 @@
+/**
+ * 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.jose.jwejws;
+
+import java.io.IOException;
+
+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.rs.security.jose.jaxrs.Priorities;
+
+@PreMatching
+@Priority(Priorities.JWS_SERVER_READ_PRIORITY - 1)
+public class HttpHeaderModifyingFilter implements ContainerRequestFilter {
+
+    @Override
+    public void filter(ContainerRequestContext ctx) throws IOException {
+        if (ctx.getHeaderString("Modify") != null) {
+            ctx.getHeaders().putSingle("Accept", "text/plain;a=b");
+        }
+        
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJwsTest.java
----------------------------------------------------------------------
diff --git 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJwsTest.java
 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJwsTest.java
index 3105777..2bd00d6 100644
--- 
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJwsTest.java
+++ 
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJwsTest.java
@@ -26,6 +26,8 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Properties;
 
+import javax.ws.rs.BadRequestException;
+
 import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
 
 import org.apache.cxf.Bus;
@@ -260,6 +262,13 @@ public class JAXRSJweJwsTest extends 
AbstractBusClientServerTestBase {
         String text = bs.echoText("book");
         assertEquals("book", text);
     }
+    @Test(expected = BadRequestException.class)
+    public void testJwsJwkPlainTextHMacHttpHeadersModified() throws Exception {
+        String address = "https://localhost:"; + PORT + 
"/jwsjwkhmacHttpHeaders";
+        BookStore bs = createJwsBookStore(address, null, true, true);
+        WebClient.client(bs).header("Modify", "true");
+        bs.echoText("book");
+    }
     @Test
     public void testJwsJwkPlainTextHMacUnencoded() throws Exception {
         String address = "https://localhost:"; + PORT + "/jwsjwkhmac";

http://git-wip-us.apache.org/repos/asf/cxf/blob/eb14ce92/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/jose/jwejws/server.xml
----------------------------------------------------------------------
diff --git 
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/jose/jwejws/server.xml
 
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/jose/jwejws/server.xml
index abc315b..786344e 100644
--- 
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/jose/jwejws/server.xml
+++ 
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/jose/jwejws/server.xml
@@ -75,6 +75,7 @@ under the License.
     <bean id="jwsInFilterHttpHeaders" 
class="org.apache.cxf.rs.security.jose.jaxrs.JwsContainerRequestFilter">
         <property name="validateHttpHeaders" value="true"/>
     </bean>
+    <bean id="httpHeaderFilter" 
class="org.apache.cxf.systest.jaxrs.security.jose.jwejws.HttpHeaderModifyingFilter"/>
     <bean id="jwsOutFilter" 
class="org.apache.cxf.rs.security.jose.jaxrs.JwsWriterInterceptor"/>
     <bean id="keyPasswordProvider" 
class="org.apache.cxf.systest.jaxrs.security.jose.jwejws.PrivateKeyPasswordProviderImpl"/>
     <bean id="keyPasswordProvider2" 
class="org.apache.cxf.systest.jaxrs.security.jose.jwejws.PrivateKeyPasswordProviderImpl">
@@ -216,6 +217,7 @@ under the License.
         </jaxrs:serviceBeans>
         <jaxrs:providers>
             <ref bean="jwsInFilterHttpHeaders"/>
+            <ref bean="httpHeaderFilter"/>
             <ref bean="jwsOutFilter"/>
             <ref bean="jackson"/>
         </jaxrs:providers>

Reply via email to