You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2022/05/09 12:41:15 UTC
[cxf] branch master updated: [CXF-8699] Abillity to set sensitive filters on LoggingFeature (#945)
This is an automated email from the ASF dual-hosted git repository.
reta 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 940e4ee9b6 [CXF-8699] Abillity to set sensitive filters on LoggingFeature (#945)
940e4ee9b6 is described below
commit 940e4ee9b6b4e9768350cf6f8e79c8d466f27d64
Author: Julien Greffe <36...@users.noreply.github.com>
AuthorDate: Mon May 9 14:41:09 2022 +0200
[CXF-8699] Abillity to set sensitive filters on LoggingFeature (#945)
* [CXF-8699] Abillity to set sensitive filters on LoggingFeature
* [CXF-8699] Set<String> with trimmed values
---
.../ext/logging/AbstractLoggingInterceptor.java | 9 +++++
.../org/apache/cxf/ext/logging/LoggingFeature.java | 42 ++++++++++++++++++++
.../cxf/ext/logging/MaskSensitiveHelper.java | 6 +++
.../org/apache/cxf/ext/logging/osgi/Activator.java | 25 ++++++++++++
.../cxf/ext/logging/MaskSensitiveHelperTest.java | 46 +++++++++++++++++++++-
5 files changed, 126 insertions(+), 2 deletions(-)
diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java
index f6b48fd045..619ce5220b 100644
--- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java
+++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java
@@ -86,10 +86,19 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto
return threshold;
}
+ public void setSensitiveElementNames(final Set<String> sensitiveElementNames) {
+ maskSensitiveHelper.setSensitiveElementNames(sensitiveElementNames);
+ }
+
public void addSensitiveElementNames(final Set<String> sensitiveElementNames) {
maskSensitiveHelper.addSensitiveElementNames(sensitiveElementNames);
}
+ public void setSensitiveProtocolHeaderNames(final Set<String> protocolHeaderNames) {
+ this.sensitiveProtocolHeaderNames.clear();
+ addSensitiveProtocolHeaderNames(protocolHeaderNames);
+ }
+
public void addSensitiveProtocolHeaderNames(final Set<String> protocolHeaderNames) {
this.sensitiveProtocolHeaderNames.addAll(protocolHeaderNames);
}
diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java
index dff3e88bed..43bedc484a 100644
--- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java
+++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/LoggingFeature.java
@@ -147,6 +147,22 @@ public class LoggingFeature extends DelegatingFeature<LoggingFeature.Portable> {
* </pre>
* @param sensitiveElementNames set of sensitive element names to be replaced
*/
+ public void setSensitiveElementNames(final Set<String> sensitiveElementNames) {
+ delegate.setSensitiveElementNames(sensitiveElementNames);
+ }
+
+ /**
+ * Adds list of XML or JSON elements containing sensitive information to be masked.
+ * Corresponded data will be replaced with configured mask
+ * For example:
+ * <pre>
+ * sensitiveElementNames: {password}
+ *
+ * Initial logging statement: <user>my user</user><password>my secret password</password>
+ * Result logging statement: <user>my user</user><password>XXXX</password>
+ * </pre>
+ * @param sensitiveElementNames set of sensitive element names to be replaced
+ */
public void addSensitiveElementNames(final Set<String> sensitiveElementNames) {
delegate.addSensitiveElementNames(sensitiveElementNames);
}
@@ -163,6 +179,22 @@ public class LoggingFeature extends DelegatingFeature<LoggingFeature.Portable> {
* </pre>
* @param sensitiveProtocolHeaderNames set of sensitive element names to be replaced
*/
+ public void setSensitiveProtocolHeaderNames(final Set<String> sensitiveProtocolHeaderNames) {
+ delegate.setSensitiveProtocolHeaderNames(sensitiveProtocolHeaderNames);
+ }
+
+ /**
+ * Adds list of protocol headers containing sensitive information to be masked.
+ * Corresponded data will be replaced with configured mask
+ * For example:
+ * <pre>
+ * sensitiveHeaders: {Authorization}
+ *
+ * Initial logging statement: {Authorization=Basic QWxhZGRpbjpPcGVuU2VzYW1l}
+ * Result logging statement: {Authorization=XXX}
+ * </pre>
+ * @param sensitiveProtocolHeaderNames set of sensitive element names to be replaced
+ */
public void addSensitiveProtocolHeaderNames(final Set<String> sensitiveProtocolHeaderNames) {
delegate.addSensitiveProtocolHeaderNames(sensitiveProtocolHeaderNames);
}
@@ -252,11 +284,21 @@ public class LoggingFeature extends DelegatingFeature<LoggingFeature.Portable> {
addOutBinaryContentMediaTypes(mediaTypes);
}
+ public void setSensitiveElementNames(final Set<String> sensitiveElementNames) {
+ in.setSensitiveElementNames(sensitiveElementNames);
+ out.setSensitiveElementNames(sensitiveElementNames);
+ }
+
public void addSensitiveElementNames(final Set<String> sensitiveElementNames) {
in.addSensitiveElementNames(sensitiveElementNames);
out.addSensitiveElementNames(sensitiveElementNames);
}
+ public void setSensitiveProtocolHeaderNames(final Set<String> sensitiveProtocolHeaderNames) {
+ in.setSensitiveProtocolHeaderNames(sensitiveProtocolHeaderNames);
+ out.setSensitiveProtocolHeaderNames(sensitiveProtocolHeaderNames);
+ }
+
public void addSensitiveProtocolHeaderNames(final Set<String> sensitiveProtocolHeaderNames) {
in.addSensitiveProtocolHeaderNames(sensitiveProtocolHeaderNames);
out.addSensitiveProtocolHeaderNames(sensitiveProtocolHeaderNames);
diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java
index 811a541254..062a0e4d4b 100644
--- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java
+++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/MaskSensitiveHelper.java
@@ -50,6 +50,12 @@ public class MaskSensitiveHelper {
private final Set<ReplacementPair> replacementsXML = new HashSet<>();
private final Set<ReplacementPair> replacementsJSON = new HashSet<>();
+ public void setSensitiveElementNames(final Set<String> inSensitiveElementNames) {
+ replacementsXML.clear();
+ replacementsJSON.clear();
+ addSensitiveElementNames(inSensitiveElementNames);
+ }
+
public void addSensitiveElementNames(final Set<String> inSensitiveElementNames) {
for (final String sensitiveName : inSensitiveElementNames) {
addReplacementPair(MATCH_PATTERN_XML_TEMPLATE, REPLACEMENT_XML_TEMPLATE, sensitiveName, replacementsXML);
diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/osgi/Activator.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/osgi/Activator.java
index 5845180add..6084bd7978 100644
--- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/osgi/Activator.java
+++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/osgi/Activator.java
@@ -18,8 +18,12 @@
*/
package org.apache.cxf.ext.logging.osgi;
+import java.util.Arrays;
import java.util.Dictionary;
+import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.cxf.ext.logging.LoggingFeature;
import org.apache.cxf.feature.AbstractFeature;
@@ -33,6 +37,8 @@ import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static java.util.function.Predicate.not;
+
public class Activator implements BundleActivator {
private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
private static final String CONFIG_PID = "org.apache.cxf.features.logging";
@@ -71,6 +77,8 @@ public class Activator implements BundleActivator {
Long inMemThreshold = Long.valueOf(getValue(config, "inMemThresHold", "-1"));
Boolean logMultipart = Boolean.valueOf(getValue(config, "logMultipart", "true"));
Boolean logBinary = Boolean.valueOf(getValue(config, "logBinary", "false"));
+ Set<String> sensitiveElementNames = getTrimmedSet(config, "sensitiveElementNames");
+ Set<String> sensitiveProtocolHeaderNames = getTrimmedSet(config, "sensitiveProtocolHeaderNames");
if (limit != null) {
logging.setLimit(limit);
@@ -91,6 +99,14 @@ public class Activator implements BundleActivator {
if (logBinary != null) {
logging.setLogBinary(logBinary);
}
+
+ if (!sensitiveElementNames.isEmpty()) {
+ logging.setSensitiveElementNames(sensitiveElementNames);
+ }
+
+ if (!sensitiveProtocolHeaderNames.isEmpty()) {
+ logging.setSensitiveProtocolHeaderNames(sensitiveProtocolHeaderNames);
+ }
if (intentReg == null) {
Dictionary<String, Object> properties = new Hashtable<>();
@@ -112,6 +128,15 @@ public class Activator implements BundleActivator {
}
}
+ @SuppressWarnings("rawtypes")
+ private Set<String> getTrimmedSet(Dictionary config, String propertyKey) {
+ return new HashSet<>(
+ Arrays.stream(String.valueOf(getValue(config, propertyKey, "")).split(","))
+ .map(String::trim)
+ .filter(not(String::isEmpty))
+ .collect(Collectors.toSet()));
+ }
+
@SuppressWarnings("rawtypes")
private String getValue(Dictionary config, String key, String defaultValue) {
if (config == null) {
diff --git a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveHelperTest.java b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveHelperTest.java
index 44ebede0c1..c6f41ccade 100644
--- a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveHelperTest.java
+++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/MaskSensitiveHelperTest.java
@@ -92,7 +92,7 @@ public class MaskSensitiveHelperTest {
}
@Test
- public void shouldReplaceSensitiveDataIn() {
+ public void shouldReplaceSensitiveDataInWithAdd() {
// Arrange
final LoggingInInterceptor inInterceptor = new LoggingInInterceptor(logEventSender);
inInterceptor.addSensitiveElementNames(SENSITIVE_ELEMENTS);
@@ -113,7 +113,28 @@ public class MaskSensitiveHelperTest {
}
@Test
- public void shouldReplaceSensitiveDataOut() throws IOException {
+ public void shouldReplaceSensitiveDataInWithSet() {
+ // Arrange
+ final LoggingInInterceptor inInterceptor = new LoggingInInterceptor(logEventSender);
+ inInterceptor.setSensitiveElementNames(SENSITIVE_ELEMENTS);
+
+ final Message message = prepareInMessage();
+
+ // Act
+ Collection<PhaseInterceptor<? extends Message>> interceptors = inInterceptor.getAdditionalInterceptors();
+ for (PhaseInterceptor intercept : interceptors) {
+ intercept.handleMessage(message);
+ }
+ inInterceptor.handleMessage(message);
+
+ // Verify
+ LogEvent event = logEventSender.getLogEvent();
+ assertNotNull(event);
+ assertEquals(maskedContent, event.getPayload());
+ }
+
+ @Test
+ public void shouldReplaceSensitiveDataOutWithAdd() throws IOException {
// Arrange
final LoggingOutInterceptor outInterceptor = new LoggingOutInterceptor(logEventSender);
outInterceptor.addSensitiveElementNames(SENSITIVE_ELEMENTS);
@@ -133,6 +154,27 @@ public class MaskSensitiveHelperTest {
assertEquals(maskedContent, event.getPayload());
}
+ @Test
+ public void shouldReplaceSensitiveDataOutWithSet() throws IOException {
+ // Arrange
+ final LoggingOutInterceptor outInterceptor = new LoggingOutInterceptor(logEventSender);
+ outInterceptor.setSensitiveElementNames(SENSITIVE_ELEMENTS);
+
+ final Message message = prepareOutMessage();
+
+ // Act
+ outInterceptor.handleMessage(message);
+ byte[] payload = loggingContent.getBytes(StandardCharsets.UTF_8);
+ OutputStream out = message.getContent(OutputStream.class);
+ out.write(payload);
+ out.close();
+
+ // Verify
+ LogEvent event = logEventSender.getLogEvent();
+ assertNotNull(event);
+ assertEquals(maskedContent, event.getPayload());
+ }
+
@Test
public void shouldNotReplaceSensitiveDataEmptyExpression() throws IOException {
// Arrange