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"/>