This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/master by this push:
     new f89a26c  Fixing how requiring default headers works for HTTP Signature
f89a26c is described below

commit f89a26cbd773ac615870dfbf3766e00f41646ea0
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Mon Apr 29 17:55:39 2019 +0100

    Fixing how requiring default headers works for HTTP Signature
---
 .../rs/security/httpsignature/MessageVerifier.java | 67 +++++++++++++++-
 .../security/httpsignature/SignatureValidator.java |  3 +-
 .../httpsignature/TomitribeSignatureCreator.java   |  2 +-
 .../httpsignature/TomitribeSignatureValidator.java | 23 ++----
 .../filters/AbstractSignatureInFilter.java         | 23 +-----
 .../httpsignature/MessageVerifierTest.java         | 90 ++++++++++++++++++----
 .../security/httpsignature/SpecExamplesTest.java   |  9 ++-
 .../jaxrs/security/httpsignature/server.xml        |  2 +
 8 files changed, 158 insertions(+), 61 deletions(-)

diff --git 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/MessageVerifier.java
 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/MessageVerifier.java
index 39a1abb..06bef9a 100644
--- 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/MessageVerifier.java
+++ 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/MessageVerifier.java
@@ -18,6 +18,7 @@
  */
 package org.apache.cxf.rs.security.httpsignature;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -25,6 +26,9 @@ import java.util.Objects;
 import java.util.logging.Logger;
 
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
 import 
org.apache.cxf.rs.security.httpsignature.exception.MissingSignatureHeaderException;
 import 
org.apache.cxf.rs.security.httpsignature.exception.MultipleSignatureHeaderException;
 import org.apache.cxf.rs.security.httpsignature.provider.AlgorithmProvider;
@@ -40,9 +44,11 @@ public class MessageVerifier {
     private KeyProvider keyProvider;
     private SecurityProvider securityProvider;
     private final SignatureValidator signatureValidator;
+    private final List<String> requiredHeaders;
+    private boolean addDefaultRequiredHeaders = true;
 
     public MessageVerifier(KeyProvider keyProvider) {
-        this(keyProvider, Collections.emptyList());
+        this(keyProvider, (List<String>)null);
     }
 
     public MessageVerifier(KeyProvider keyProvider, List<String> 
requiredHeaders) {
@@ -67,10 +73,19 @@ public class MessageVerifier {
                            SecurityProvider securityProvider,
                            AlgorithmProvider algorithmProvider,
                            List<String> requiredHeaders) {
+        this(keyProvider, securityProvider, algorithmProvider, 
requiredHeaders, new TomitribeSignatureValidator());
+    }
+
+    public MessageVerifier(KeyProvider keyProvider,
+                           SecurityProvider securityProvider,
+                           AlgorithmProvider algorithmProvider,
+                           List<String> requiredHeaders,
+                           SignatureValidator signatureValidator) {
         setkeyProvider(keyProvider);
         setSecurityProvider(securityProvider);
         setAlgorithmProvider(algorithmProvider);
-        this.signatureValidator = new 
TomitribeSignatureValidator(requiredHeaders);
+        this.requiredHeaders = requiredHeaders == null ? 
Collections.emptyList() : requiredHeaders;
+        this.signatureValidator = signatureValidator;
     }
 
     public final void setkeyProvider(KeyProvider provider) {
@@ -86,18 +101,50 @@ public class MessageVerifier {
         this.algorithmProvider = Objects.requireNonNull(algorithmProvider, 
"algorithm provider cannot be null");
     }
 
-    public void verifyMessage(Map<String, List<String>> messageHeaders, String 
method, String uri) {
+    public void verifyMessage(Map<String, List<String>> messageHeaders, String 
method, String uri, Message m) {
         SignatureHeaderUtils.inspectMessageHeaders(messageHeaders);
         inspectMissingSignatureHeader(messageHeaders);
 
         inspectMultipleSignatureHeaders(messageHeaders);
+
+        // Calculate the headers that we require to be signed. Use the headers 
configured on this class if available,
+        // falling back to the contextual property.
+        List<String> signedHeaders = new ArrayList<>(requiredHeaders);
+        if (requiredHeaders.isEmpty()
+            && 
m.getContextualProperty(HTTPSignatureConstants.RSSEC_HTTP_SIGNATURE_IN_HEADERS) 
!= null) {
+            signedHeaders =
+                CastUtils.cast(
+                    
(List<?>)m.getContextualProperty(HTTPSignatureConstants.RSSEC_HTTP_SIGNATURE_IN_HEADERS));
+        }
+
+        // Add the default required headers
+        boolean requestor = MessageUtils.isRequestor(m);
+        if (addDefaultRequiredHeaders) {
+            if (!(requestor || 
signedHeaders.contains(HTTPSignatureConstants.REQUEST_TARGET))) {
+                signedHeaders.add(HTTPSignatureConstants.REQUEST_TARGET);
+            }
+            if (!signedHeaders.contains("digest")) {
+                signedHeaders.add("digest");
+            }
+        }
+
+        // Now dynamically check to see whether the "digest" header is 
required or not. It's not required
+        // for the service case on a GET/HEAD request as there is no request, 
and also not required on
+        // the client side unless it is an OK response that is not 204
+        Integer status = (Integer)m.get(Message.RESPONSE_CODE);
+        if ((requestor && (status < 200 || status >= 300 || status == 204))
+            || (!requestor && ("GET".equalsIgnoreCase(method) || 
"HEAD".equalsIgnoreCase(method)))) {
+            signedHeaders.remove("digest");
+        }
+
         LOG.fine("Starting signature verification");
         signatureValidator.validate(messageHeaders,
                                     algorithmProvider,
                                     keyProvider,
                                     securityProvider,
                                     method,
-                                    uri);
+                                    uri,
+                                    signedHeaders);
         LOG.fine("Finished signature verification");
     }
 
@@ -113,4 +160,16 @@ public class MessageVerifier {
         }
     }
 
+    public boolean isAddDefaultRequiredHeaders() {
+        return addDefaultRequiredHeaders;
+    }
+
+    /**
+     * Set whether we require some default headers to be signed, such as 
"digest" and "(request-target"),
+     * depending on whether there is a request body or not, and whether we are 
the client or not
+     */
+    public void setAddDefaultRequiredHeaders(boolean 
addDefaultRequiredHeaders) {
+        this.addDefaultRequiredHeaders = addDefaultRequiredHeaders;
+    }
+
 }
diff --git 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/SignatureValidator.java
 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/SignatureValidator.java
index 10e8457..de2de07 100644
--- 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/SignatureValidator.java
+++ 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/SignatureValidator.java
@@ -31,6 +31,7 @@ public interface SignatureValidator {
                   KeyProvider keyProvider,
                   SecurityProvider securityProvider,
                   String method,
-                  String uri);
+                  String uri,
+                  List<String> requiredHeaders);
 
 }
diff --git 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureCreator.java
 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureCreator.java
index 3c45ed2..0dc4a26 100644
--- 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureCreator.java
+++ 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureCreator.java
@@ -60,7 +60,7 @@ public class TomitribeSignatureCreator implements 
SignatureCreator {
 
         List<String> headers = null;
         // If we have explicit headers to sign then use these.
-        // Otherwise sign all headers including "(request-target)" (if on an 
inbound service request)
+        // Otherwise sign all headers including "(request-target)" (if on an 
outbound service request)
         if (headersToSign.isEmpty()) {
             headers = 
messageHeaders.keySet().stream().map(String::toLowerCase).collect(Collectors.toList());
             Message m = PhaseInterceptorChain.getCurrentMessage();
diff --git 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureValidator.java
 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureValidator.java
index 52d2a0a..69fc901 100644
--- 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureValidator.java
+++ 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/TomitribeSignatureValidator.java
@@ -19,8 +19,6 @@
 package org.apache.cxf.rs.security.httpsignature;
 
 import java.security.Key;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
@@ -39,11 +37,6 @@ import org.tomitribe.auth.signatures.Verifier;
 
 public class TomitribeSignatureValidator implements SignatureValidator {
     private static final Logger LOG = 
LogUtils.getL7dLogger(TomitribeSignatureValidator.class);
-    private final List<String> requiredHeaders;
-
-    public TomitribeSignatureValidator(List<String> requiredHeaders) {
-        this.requiredHeaders = requiredHeaders != null ? new 
ArrayList<>(requiredHeaders) : Collections.emptyList();
-    }
 
     @Override
     public void validate(Map<String, List<String>> messageHeaders,
@@ -51,7 +44,8 @@ public class TomitribeSignatureValidator implements 
SignatureValidator {
                          KeyProvider keyProvider,
                          SecurityProvider securityProvider,
                          String method,
-                         String uri) {
+                         String uri,
+                         List<String> requiredHeaders) {
         Signature signature = 
extractSignatureFromHeader(messageHeaders.get("Signature").get(0));
 
         String providedAlgorithm = 
algorithmProvider.getAlgorithmName(signature.getKeyId());
@@ -66,7 +60,7 @@ public class TomitribeSignatureValidator implements 
SignatureValidator {
         java.security.Provider provider =
             securityProvider != null ? 
securityProvider.getProvider(signature.getKeyId()) : null;
 
-        runVerifier(messageHeaders, key, signature, provider, method, uri);
+        runVerifier(messageHeaders, key, signature, provider, method, uri, 
requiredHeaders);
     }
 
     private static Signature extractSignatureFromHeader(String 
signatureString) {
@@ -82,20 +76,15 @@ public class TomitribeSignatureValidator implements 
SignatureValidator {
                              Signature signature,
                              java.security.Provider provider,
                              String method,
-                             String uri) {
+                             String uri,
+                             List<String> requiredHeaders) {
         LOG.fine("Starting signature validation");
         boolean success;
         try {
             Verifier verifier = new Verifier(key, signature, provider);
             success = verifier.verify(method, uri, 
SignatureHeaderUtils.mapHeaders(messageHeaders));
 
-            // If HTTP GET then don't require that the digest is present
-            List<String> headers = requiredHeaders;
-            if ("GET".equals(method)) {
-                headers = new ArrayList<>(requiredHeaders);
-                headers.remove("digest");
-            }
-            if (!signature.getHeaders().containsAll(headers)) {
+            if (!signature.getHeaders().containsAll(requiredHeaders)) {
                 LOG.warning("Not all of the required headers are signed");
                 throw new InvalidDataToVerifySignatureException();
             }
diff --git 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/filters/AbstractSignatureInFilter.java
 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/filters/AbstractSignatureInFilter.java
index 534684d..5b51883 100644
--- 
a/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/filters/AbstractSignatureInFilter.java
+++ 
b/rt/rs/security/http-signature/src/main/java/org/apache/cxf/rs/security/httpsignature/filters/AbstractSignatureInFilter.java
@@ -23,9 +23,6 @@ import java.io.InputStream;
 import java.security.Provider;
 import java.security.PublicKey;
 import java.security.Security;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
 import java.util.Properties;
 import java.util.logging.Logger;
@@ -34,7 +31,6 @@ import javax.ws.rs.BadRequestException;
 import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
@@ -102,7 +98,8 @@ abstract class AbstractSignatureInFilter {
         return messageBody;
     }
 
-    protected void verifySignature(MultivaluedMap<String, String> headers, 
String uriPath, String httpMethod) {
+    protected void verifySignature(MultivaluedMap<String, String> headers, 
String uriPath,
+                                   String httpMethod) {
         if (!enabled) {
             LOG.fine("Verify signature filter is disabled");
             return;
@@ -114,7 +111,7 @@ abstract class AbstractSignatureInFilter {
 
         LOG.fine("Starting filter message verification process");
         try {
-            messageVerifier.verifyMessage(headers, httpMethod, uriPath);
+            messageVerifier.verifyMessage(headers, httpMethod, uriPath, 
PhaseInterceptorChain.getCurrentMessage());
         } catch (DifferentAlgorithmsException | InvalidSignatureHeaderException
             | InvalidDataToVerifySignatureException | InvalidSignatureException
             | MultipleSignatureHeaderException | 
MissingSignatureHeaderException ex) {
@@ -151,21 +148,9 @@ abstract class AbstractSignatureInFilter {
             signatureAlgorithm = DefaultSignatureConstants.SIGNING_ALGORITHM;
         }
 
-        List<String> signedHeaders =
-            
CastUtils.cast((List<?>)m.getContextualProperty(HTTPSignatureConstants.RSSEC_HTTP_SIGNATURE_IN_HEADERS));
-        if (signedHeaders == null) {
-            if (!MessageUtils.isRequestor(m)) {
-                 // The service request must contain "(request-target)" + 
"digest" by default
-                signedHeaders = 
Arrays.asList(HTTPSignatureConstants.REQUEST_TARGET, "digest");
-            } else {
-                signedHeaders = Collections.emptyList();
-            }
-        }
-
         final String finalSignatureAlgorithm = signatureAlgorithm;
         final Provider provider = 
Security.getProvider(DefaultSignatureConstants.SECURITY_PROVIDER);
-        return new MessageVerifier(keyId -> publicKey, keyId -> provider, 
keyId -> finalSignatureAlgorithm,
-            signedHeaders);
+        return new MessageVerifier(keyId -> publicKey, keyId -> provider, 
keyId -> finalSignatureAlgorithm);
     }
 
     protected abstract void handleException(Exception ex);
diff --git 
a/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/MessageVerifierTest.java
 
b/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/MessageVerifierTest.java
index 90f9078..873ccf3 100644
--- 
a/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/MessageVerifierTest.java
+++ 
b/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/MessageVerifierTest.java
@@ -32,6 +32,7 @@ import java.util.Map;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 
+import org.apache.cxf.message.MessageImpl;
 import 
org.apache.cxf.rs.security.httpsignature.exception.DifferentAlgorithmsException;
 import 
org.apache.cxf.rs.security.httpsignature.exception.InvalidDataToVerifySignatureException;
 import 
org.apache.cxf.rs.security.httpsignature.exception.InvalidSignatureException;
@@ -64,6 +65,7 @@ public class MessageVerifierTest {
             messageVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic());
             messageVerifier.setSecurityProvider(new MockSecurityProvider());
             messageVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
+            messageVerifier.setAddDefaultRequiredHeaders(false);
 
             messageSigner = new MessageSigner(keyId -> keyPair.getPrivate(), 
KEY_ID);
 
@@ -76,14 +78,14 @@ public class MessageVerifierTest {
     public void validUnalteredRequest() throws IOException {
         Map<String, List<String>> headers = createMockHeaders();
         createAndAddSignature(headers);
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test
     public void validUnalteredRequestWithoutBody() throws IOException {
         Map<String, List<String>> headers = createMockHeaders();
         createAndAddSignature(headers);
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test
@@ -92,7 +94,7 @@ public class MessageVerifierTest {
         createAndAddSignature(headers);
         headers.put("Test", Collections.singletonList("value"));
         headers.put("Test2", Collections.singletonList("value2"));
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = DifferentAlgorithmsException.class)
@@ -102,7 +104,7 @@ public class MessageVerifierTest {
         String signature = headers.get("Signature").get(0);
         signature = signature.replaceFirst("algorithm=\"rsa-sha256", 
"algorithm=\"hmac-sha256");
         headers.replace("Signature", Collections.singletonList(signature));
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = InvalidDataToVerifySignatureException.class)
@@ -110,7 +112,7 @@ public class MessageVerifierTest {
         Map<String, List<String>> headers = createMockHeaders();
         createAndAddSignature(headers);
         headers.remove("Content-Length");
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = InvalidSignatureException.class)
@@ -120,7 +122,7 @@ public class MessageVerifierTest {
         String signature = headers.get("Signature").get(0);
         signature = signature.replaceFirst("signature=\".{10}", 
"signature=\"AAAAAAAAAA");
         headers.replace("Signature", Collections.singletonList(signature));
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = InvalidSignatureHeaderException.class)
@@ -130,13 +132,13 @@ public class MessageVerifierTest {
         String signature = headers.get("Signature").get(0);
         signature = signature.replaceFirst(",signature", ",signature2");
         headers.replace("Signature", Collections.singletonList(signature));
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = MissingSignatureHeaderException.class)
     public void missingSignatureHeaderFails() {
         Map<String, List<String>> headers = createMockHeaders();
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = MultipleSignatureHeaderException.class)
@@ -147,7 +149,7 @@ public class MessageVerifierTest {
         List<String> signatureList = new ArrayList<>(headers.get("Signature"));
         signatureList.add(signature);
         headers.put("Signature", signatureList);
-        messageVerifier.verifyMessage(headers, METHOD, URI);
+        messageVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test
@@ -163,7 +165,8 @@ public class MessageVerifierTest {
 
         MessageVerifier hmacMessageVerifier =
             new MessageVerifier(keyId -> secretKey, null, keyId -> 
"hmac-sha256", Collections.emptyList());
-        hmacMessageVerifier.verifyMessage(headers, METHOD, URI);
+        hmacMessageVerifier.setAddDefaultRequiredHeaders(false);
+        hmacMessageVerifier.verifyMessage(headers, METHOD, URI, new 
MessageImpl());
     }
 
     @Test
@@ -173,10 +176,11 @@ public class MessageVerifierTest {
         createAndAddSignature(headers);
 
         MessageVerifier headerVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic(),
-                                                              
Collections.singletonList("test"));
+                                                             
Collections.singletonList("test"));
+        headerVerifier.setAddDefaultRequiredHeaders(false);
         headerVerifier.setSecurityProvider(new MockSecurityProvider());
         headerVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
-        headerVerifier.verifyMessage(headers, METHOD, URI);
+        headerVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = InvalidDataToVerifySignatureException.class)
@@ -186,10 +190,11 @@ public class MessageVerifierTest {
         headers.put("Test", Collections.singletonList("value"));
 
         MessageVerifier headerVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic(),
-                                                              
Collections.singletonList("test"));
+                                                             
Collections.singletonList("test"));
+        headerVerifier.setAddDefaultRequiredHeaders(false);
         headerVerifier.setSecurityProvider(new MockSecurityProvider());
         headerVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
-        headerVerifier.verifyMessage(headers, METHOD, URI);
+        headerVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     @Test(expected = InvalidDataToVerifySignatureException.class)
@@ -198,10 +203,63 @@ public class MessageVerifierTest {
         createAndAddSignature(headers);
 
         MessageVerifier headerVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic(),
-                                                              
Collections.singletonList("test"));
+                                                             
Collections.singletonList("test"));
+        headerVerifier.setAddDefaultRequiredHeaders(false);
         headerVerifier.setSecurityProvider(new MockSecurityProvider());
         headerVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
-        headerVerifier.verifyMessage(headers, METHOD, URI);
+        headerVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
+    }
+
+    @Test
+    public void defaultRequiredHeaderPresent() throws IOException {
+        Map<String, List<String>> headers = createMockHeaders();
+        headers.put("Test", Collections.singletonList("value"));
+        headers.put(HTTPSignatureConstants.REQUEST_TARGET, 
Collections.singletonList("12345"));
+        createAndAddSignature(headers);
+
+        MessageVerifier headerVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic(),
+                                                             
Collections.singletonList("test"));
+        headerVerifier.setSecurityProvider(new MockSecurityProvider());
+        headerVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
+        headerVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
+    }
+
+    @Test
+    public void defaultRequiredHeaderPresentTestNotRequired() throws 
IOException {
+        Map<String, List<String>> headers = createMockHeaders();
+        headers.put("Test", Collections.singletonList("value"));
+        headers.put(HTTPSignatureConstants.REQUEST_TARGET, 
Collections.singletonList("12345"));
+        createAndAddSignature(headers);
+
+        MessageVerifier headerVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic());
+        headerVerifier.setSecurityProvider(new MockSecurityProvider());
+        headerVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
+        headerVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
+    }
+
+    @Test(expected = InvalidDataToVerifySignatureException.class)
+    public void defaultRequiredHeaderNotPresent() throws IOException {
+        Map<String, List<String>> headers = createMockHeaders();
+        headers.put("Test", Collections.singletonList("value"));
+        createAndAddSignature(headers);
+
+        MessageVerifier headerVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic(),
+                                                             
Collections.singletonList("test"));
+        headerVerifier.setSecurityProvider(new MockSecurityProvider());
+        headerVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
+        headerVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
+    }
+
+    @Test(expected = InvalidDataToVerifySignatureException.class)
+    public void defaultRequiredHeaderNotPresentTestNotRequired() throws 
IOException {
+        Map<String, List<String>> headers = createMockHeaders();
+        headers.put("Test", Collections.singletonList("value"));
+        createAndAddSignature(headers);
+
+        MessageVerifier headerVerifier = new MessageVerifier(keyId -> 
keyPair.getPublic());
+        headerVerifier.setSecurityProvider(new MockSecurityProvider());
+        headerVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
+        headerVerifier.verifyMessage(headers, METHOD, URI, new MessageImpl());
     }
 
     private static void createAndAddSignature(Map<String, List<String>> 
headers) throws IOException {
diff --git 
a/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/SpecExamplesTest.java
 
b/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/SpecExamplesTest.java
index 971cbbe..6d164c2 100644
--- 
a/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/SpecExamplesTest.java
+++ 
b/rt/rs/security/http-signature/src/test/java/org/apache/cxf/rs/security/httpsignature/SpecExamplesTest.java
@@ -36,6 +36,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.cxf.message.MessageImpl;
 import org.apache.cxf.rs.security.httpsignature.provider.KeyProvider;
 import org.apache.cxf.rs.security.httpsignature.provider.MockAlgorithmProvider;
 import org.apache.cxf.rs.security.httpsignature.provider.MockSecurityProvider;
@@ -100,9 +101,10 @@ public class SpecExamplesTest {
         // Now check we validate the Date header as expected on an empty 
header list
         headers.put("Signature", Collections.singletonList(expectedHeader));
         MessageVerifier messageVerifier = new MessageVerifier(keyId -> 
publicKey);
+        messageVerifier.setAddDefaultRequiredHeaders(false);
         messageVerifier.setSecurityProvider(new MockSecurityProvider());
         messageVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
-        messageVerifier.verifyMessage(headers, "POST", 
"/foo?param=value&pet=dog");
+        messageVerifier.verifyMessage(headers, "POST", 
"/foo?param=value&pet=dog", new MessageImpl());
     }
 
     @Test
@@ -123,9 +125,10 @@ public class SpecExamplesTest {
         assertEquals(signatureHeader, expectedHeader);
 
         MessageVerifier messageVerifier = new MessageVerifier(keyId -> 
publicKey);
+        messageVerifier.setAddDefaultRequiredHeaders(false);
         messageVerifier.setSecurityProvider(new MockSecurityProvider());
         messageVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
-        messageVerifier.verifyMessage(headers, "POST", 
"/foo?param=value&pet=dog");
+        messageVerifier.verifyMessage(headers, "POST", 
"/foo?param=value&pet=dog", new MessageImpl());
     }
 
     @Test
@@ -149,7 +152,7 @@ public class SpecExamplesTest {
         MessageVerifier messageVerifier = new MessageVerifier(keyId -> 
publicKey);
         messageVerifier.setSecurityProvider(new MockSecurityProvider());
         messageVerifier.setAlgorithmProvider(new MockAlgorithmProvider());
-        messageVerifier.verifyMessage(headers, "POST", 
"/foo?param=value&pet=dog");
+        messageVerifier.verifyMessage(headers, "POST", 
"/foo?param=value&pet=dog", new MessageImpl());
     }
 
     private static Map<String, List<String>> createMockHeaders() {
diff --git 
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/httpsignature/server.xml
 
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/httpsignature/server.xml
index 3dae167..175d945 100644
--- 
a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/httpsignature/server.xml
+++ 
b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/httpsignature/server.xml
@@ -45,6 +45,7 @@ under the License.
                 <value>(request-target)</value>
             </util:list>
         </constructor-arg>
+        <property name="addDefaultRequiredHeaders" value="false"/>
     </bean>
     <bean id="httpSignatureVerifier" 
class="org.apache.cxf.rs.security.httpsignature.filters.VerifySignatureFilter">
         <property name="messageVerifier" ref="messageVerifier"/>
@@ -80,6 +81,7 @@ under the License.
         <constructor-arg>
             <ref bean="customAlgorithmProvider"/>
         </constructor-arg>
+        <property name="addDefaultRequiredHeaders" value="false"/>
     </bean>
     <bean id="httpSignatureVerifierRsaSha512" 
class="org.apache.cxf.rs.security.httpsignature.filters.VerifySignatureFilter">
         <property name="messageVerifier" ref="messageVerifierRsaSha512"/>

Reply via email to