Last active
October 5, 2020 14:47
-
-
Save sachin-handiekar/14b2ec8665f894970da1 to your computer and use it in GitHub Desktop.
Masking Sensitive Information in CXF Logging Interceptor for incoming/outgoing SOAP request. (http://www.sachinhandiekar.com/2014/11/cxf-logging-interceptor-masking.html)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:cxf="http://camel.apache.org/schema/blueprint/cxf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | |
<!-- Sample WS --> | |
<cxf:cxfEndpoint xmlns:e="http://com.sachinhandiekar/examples/SampleWS/" | |
id="SampleWSEndpoint" | |
address="/SampleWS" | |
endpointName="e:SampleWSPort" | |
serviceName="e:SampleWSService" | |
serviceClass="com.sachinhandiekar.examples.ws.SampleWS" | |
wsdlURL="wsdl/SampleWS.wsdl"> | |
<cxf:inInterceptors> | |
<ref component-id="secureLoggingInInterceptor" /> | |
</cxf:inInterceptors> | |
<cxf:outInterceptors> | |
<ref component-id="secureLoggingOutInterceptor" /> | |
</cxf:outInterceptors> | |
</cxf:cxfEndpoint> | |
<bean id="secureLoggingUtil" | |
class="com.sachinhandiekar.examples.cxf.logging.SecureLoggingUtil"> | |
<property name="maskingChar" value="*" /> | |
<property name="secureFields" value="userName" /> | |
</bean> | |
<!-- end of processor --> | |
<bean id="secureLoggingInInterceptor" | |
class="com.sachinhandiekar.examples.cxf.logging.SensitiveCXFLoggingInInterceptor"> | |
<property name="secureLoggingUtil" ref="secureLoggingUtil" /> | |
<property name="secureFieldStatus" value="true" /> | |
</bean> | |
<bean id="secureLoggingOutInterceptor" | |
class="com.sachinhandiekar.examples.cxf.logging.SensitiveCXFLoggingOutInterceptor"> | |
<property name="secureLoggingUtil" ref="secureLoggingUtil" /> | |
<property name="secureFieldStatus" value="true" /> | |
</bean> | |
</blueprint> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sachinhandiekar.examples.cxf.logging; | |
import java.io.ByteArrayInputStream; | |
import java.io.StringWriter; | |
import java.util.Arrays; | |
import java.util.List; | |
import javax.xml.parsers.DocumentBuilder; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
import javax.xml.transform.OutputKeys; | |
import javax.xml.transform.Source; | |
import javax.xml.transform.Transformer; | |
import javax.xml.transform.TransformerFactory; | |
import javax.xml.transform.dom.DOMSource; | |
import javax.xml.transform.stream.StreamResult; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.Node; | |
import org.w3c.dom.NodeList; | |
public class SecureLoggingUtil { | |
private String maskingChar; | |
private String secureFields; | |
private static final String REGEX_SPLIT = ","; | |
public String maskSensitiveInformation(final String inputXmlString) { | |
List<String> sensitiveFieldsList = Arrays.asList(secureFields.split(REGEX_SPLIT)); | |
try { | |
Document document = loadXMLFromString(inputXmlString); | |
NodeList nodeList = document.getElementsByTagName("*"); | |
for (int i = 0; i < nodeList.getLength(); i++) { | |
Node node = nodeList.item(i); | |
if (node.getNodeType() == Node.ELEMENT_NODE) { | |
// do something with the current element | |
for (String sensitiveField : sensitiveFieldsList) { | |
if (node.getNodeName().contains(sensitiveField)) { | |
String maskString = buildMask(node.getTextContent()); | |
node.setTextContent(maskString); | |
} | |
} | |
} | |
} | |
// prepare the DOM document for writing | |
Source domSource = new DOMSource(document); | |
StringWriter writer = new StringWriter(); | |
StreamResult result = new StreamResult(writer); | |
TransformerFactory tf = TransformerFactory.newInstance(); | |
Transformer transformer = tf.newTransformer(); | |
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
transformer.transform(domSource, result); | |
return writer.toString(); | |
} | |
catch (Exception ex) { | |
throw new RuntimeException("Failed to replace the element value.", ex); | |
} | |
} | |
private Document loadXMLFromString(String xml) throws Exception { | |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
// factory.setNamespaceAware(true); | |
DocumentBuilder builder = factory.newDocumentBuilder(); | |
return builder.parse(new ByteArrayInputStream(xml.getBytes())); | |
} | |
private String buildMask(String maskingValue) { | |
char[] mask = new char[maskingValue.length()]; | |
Arrays.fill(mask, maskingChar.charAt(0)); | |
return new String(mask); | |
} | |
public String getMaskingChar() { | |
return maskingChar; | |
} | |
public void setMaskingChar(String maskingChar) { | |
this.maskingChar = maskingChar; | |
} | |
public String getSecureFields() { | |
return secureFields; | |
} | |
public void setSecureFields(String secureFields) { | |
this.secureFields = secureFields; | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sachinhandiekar.examples.cxf.logging; | |
import java.io.FilterWriter; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.io.StringReader; | |
import java.io.StringWriter; | |
import java.io.Writer; | |
import java.nio.charset.Charset; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.xml.transform.OutputKeys; | |
import javax.xml.transform.Transformer; | |
import javax.xml.transform.stream.StreamResult; | |
import javax.xml.transform.stream.StreamSource; | |
import org.apache.commons.io.IOUtils; | |
import org.apache.cxf.common.logging.LogUtils; | |
import org.apache.cxf.common.util.StringUtils; | |
import org.apache.cxf.helpers.XMLUtils; | |
import org.apache.cxf.interceptor.Fault; | |
import org.apache.cxf.interceptor.LoggingMessage; | |
import org.apache.cxf.interceptor.LoggingOutInterceptor; | |
import org.apache.cxf.io.CacheAndWriteOutputStream; | |
import org.apache.cxf.io.CachedOutputStream; | |
import org.apache.cxf.io.CachedOutputStreamCallback; | |
import org.apache.cxf.message.Message; | |
import org.apache.cxf.service.model.EndpointInfo; | |
import org.apache.cxf.service.model.InterfaceInfo; | |
public class SensitiveCXFLoggingOutInterceptor extends LoggingOutInterceptor { | |
private static final String LOG_SETUP = LoggingOutInterceptor.class.getName() + ".log-setup"; | |
public void handleMessage(Message message) throws Fault { | |
final OutputStream os = message.getContent(OutputStream.class); | |
final Writer iowriter = message.getContent(Writer.class); | |
if (os == null && iowriter == null) { | |
return; | |
} | |
Logger logger = getMessageLogger(message); | |
if (logger.isLoggable(Level.INFO) || writer != null) { | |
// Write the output while caching it for the log message | |
boolean hasLogged = message.containsKey(LOG_SETUP); | |
if (!hasLogged) { | |
message.put(LOG_SETUP, Boolean.TRUE); | |
if (os != null) { | |
final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os); | |
if (threshold > 0) { | |
newOut.setThreshold(threshold); | |
} | |
message.setContent(OutputStream.class, newOut); | |
newOut.registerCallback(new LoggingCallback(logger, message, os)); | |
} | |
else { | |
message.setContent(Writer.class, new LogWriter(logger, message, iowriter)); | |
} | |
} | |
} | |
} | |
private LoggingMessage setupBuffer(Message message) { | |
String id = (String) message.getExchange().get(LoggingMessage.ID_KEY); | |
if (id == null) { | |
id = LoggingMessage.nextId(); | |
message.getExchange().put(LoggingMessage.ID_KEY, id); | |
} | |
final LoggingMessage buffer = new LoggingMessage("Outbound Message\n---------------------------", id); | |
Integer responseCode = (Integer) message.get(Message.RESPONSE_CODE); | |
if (responseCode != null) { | |
buffer.getResponseCode().append(responseCode); | |
} | |
String encoding = (String) message.get(Message.ENCODING); | |
if (encoding != null) { | |
buffer.getEncoding().append(encoding); | |
} | |
String httpMethod = (String) message.get(Message.HTTP_REQUEST_METHOD); | |
if (httpMethod != null) { | |
buffer.getHttpMethod().append(httpMethod); | |
} | |
String address = (String) message.get(Message.ENDPOINT_ADDRESS); | |
if (address != null) { | |
buffer.getAddress().append(address); | |
} | |
String ct = (String) message.get(Message.CONTENT_TYPE); | |
if (ct != null) { | |
buffer.getContentType().append(ct); | |
} | |
Object headers = message.get(Message.PROTOCOL_HEADERS); | |
if (headers != null) { | |
buffer.getHeader().append(headers); | |
} | |
return buffer; | |
} | |
private class LogWriter extends FilterWriter { | |
StringWriter out2; | |
int count; | |
Logger logger; // NOPMD | |
Message message; | |
public LogWriter(Logger logger, Message message, Writer writer) { | |
super(writer); | |
this.logger = logger; | |
this.message = message; | |
if (!(writer instanceof StringWriter)) { | |
out2 = new StringWriter(); | |
} | |
} | |
public void write(int c) throws IOException { | |
super.write(c); | |
if (out2 != null && count < limit) { | |
out2.write(c); | |
} | |
count++; | |
} | |
public void write(char[] cbuf, int off, int len) throws IOException { | |
super.write(cbuf, off, len); | |
if (out2 != null && count < limit) { | |
out2.write(cbuf, off, len); | |
} | |
count += len; | |
} | |
public void write(String str, int off, int len) throws IOException { | |
super.write(str, off, len); | |
if (out2 != null && count < limit) { | |
out2.write(str, off, len); | |
} | |
count += len; | |
} | |
public void close() throws IOException { | |
LoggingMessage buffer = setupBuffer(message); | |
if (count >= limit) { | |
buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); | |
} | |
StringWriter w2 = out2; | |
if (w2 == null) { | |
w2 = (StringWriter) out; | |
} | |
String ct = (String) message.get(Message.CONTENT_TYPE); | |
try { | |
writePayload(buffer.getPayload(), w2, ct); | |
} | |
catch (Exception ex) { | |
// ignore | |
} | |
log(logger, buffer.toString()); | |
message.setContent(Writer.class, out); | |
super.close(); | |
} | |
} | |
protected String formatLoggingMessage(LoggingMessage buffer) { | |
return buffer.toString(); | |
} | |
class LoggingCallback implements CachedOutputStreamCallback { | |
private final Message message; | |
private final OutputStream origStream; | |
private final Logger logger; // NOPMD | |
public LoggingCallback(final Logger logger, final Message msg, final OutputStream os) { | |
this.logger = logger; | |
this.message = msg; | |
this.origStream = os; | |
} | |
public void onFlush(CachedOutputStream cos) { | |
} | |
public void onClose(CachedOutputStream cos) { | |
LoggingMessage buffer = setupBuffer(message); | |
String ct = (String) message.get(Message.CONTENT_TYPE); | |
if (!isShowBinaryContent() && isBinaryContent(ct)) { | |
buffer.getMessage().append(BINARY_CONTENT_MESSAGE).append('\n'); | |
log(logger, formatLoggingMessage(buffer)); | |
return; | |
} | |
if (cos.getTempFile() == null) { | |
// buffer.append("Outbound Message:\n"); | |
if (cos.size() > limit) { | |
buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); | |
} | |
} | |
else { | |
buffer.getMessage().append("Outbound Message (saved to tmp file):\n"); | |
buffer.getMessage().append("Filename: " + cos.getTempFile().getAbsolutePath() + "\n"); | |
if (cos.size() > limit) { | |
buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); | |
} | |
} | |
try { | |
String encoding = (String) message.get(Message.ENCODING); | |
writePayload(buffer.getPayload(), cos, encoding, ct); | |
} | |
catch (Exception ex) { | |
// ignore | |
} | |
log(logger, formatLoggingMessage(buffer)); | |
try { | |
// empty out the cache | |
cos.lockOutputStream(); | |
cos.resetOut(null, false); | |
} | |
catch (Exception ex) { | |
// ignore | |
} | |
message.setContent(OutputStream.class, origStream); | |
} | |
} | |
Logger getMessageLogger(Message message) { | |
EndpointInfo endpoint = message.getExchange().getEndpoint().getEndpointInfo(); | |
if (endpoint.getService() == null) { | |
return getLogger(); | |
} | |
Logger logger = endpoint.getProperty("MessageLogger", Logger.class); | |
if (logger == null) { | |
String serviceName = endpoint.getService().getName().getLocalPart(); | |
InterfaceInfo iface = endpoint.getService().getInterface(); | |
String portName = endpoint.getName().getLocalPart(); | |
String portTypeName = iface.getName().getLocalPart(); | |
String logName = "org.apache.cxf.services." + serviceName + "." + portName + "." + portTypeName; | |
logger = LogUtils.getL7dLogger(this.getClass(), null, logName); | |
endpoint.setProperty("MessageLogger", logger); | |
} | |
return logger; | |
} | |
protected void writePayload(StringBuilder builder, CachedOutputStream cos, String encoding, String contentType) | |
throws Exception { | |
if (isSecureFieldStatus()) { | |
StringWriter strWriter = new StringWriter(); | |
InputStream inputStream = cos.getInputStream(); | |
IOUtils.copy(inputStream, strWriter, "UTF-8"); | |
String protectedContent = secureLoggingUtil.maskSensitiveInformation(strWriter.toString()); | |
CachedOutputStream ncos = new CachedOutputStream(); | |
ncos.write(protectedContent.toString().getBytes(Charset.forName("UTF-8"))); | |
cos = ncos; | |
} | |
// Just transform the XML message when the cos has content | |
if (isPrettyLogging() | |
&& (contentType != null && contentType.indexOf("xml") >= 0 && contentType.toLowerCase().indexOf( | |
"multipart/related") < 0) && cos.size() > 0) { | |
Transformer serializer = XMLUtils.newTransformer(2); | |
// Setup indenting to "pretty print" | |
serializer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); | |
StringWriter swriter = new StringWriter(); | |
serializer.transform(new StreamSource(cos.getInputStream()), new StreamResult(swriter)); | |
String result = swriter.toString(); | |
if (result.length() < limit || limit == -1) { | |
builder.append(swriter.toString()); | |
} | |
else { | |
builder.append(swriter.toString().substring(0, limit)); | |
} | |
} | |
else { | |
if (StringUtils.isEmpty(encoding)) { | |
cos.writeCacheTo(builder, limit); | |
} | |
else { | |
cos.writeCacheTo(builder, encoding, limit); | |
} | |
} | |
} | |
protected void writePayload(StringBuilder builder, StringWriter stringWriter, String contentType) throws Exception { | |
// Just transform the XML message when the cos has content | |
if (isPrettyLogging() && contentType != null && contentType.indexOf("xml") >= 0 | |
&& stringWriter.getBuffer().length() > 0) { | |
Transformer serializer = XMLUtils.newTransformer(2); | |
// Setup indenting to "pretty print" | |
serializer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); | |
StringWriter swriter = new StringWriter(); | |
serializer.transform(new StreamSource(new StringReader(stringWriter.getBuffer().toString())), | |
new StreamResult(swriter)); | |
String result = swriter.toString(); | |
if (result.length() < limit || limit == -1) { | |
builder.append(swriter.toString()); | |
} | |
else { | |
builder.append(swriter.toString().substring(0, limit)); | |
} | |
} | |
else { | |
StringBuffer buffer = stringWriter.getBuffer(); | |
if (buffer.length() > limit) { | |
builder.append(buffer.subSequence(0, limit)); | |
} | |
else { | |
builder.append(buffer); | |
} | |
} | |
} | |
private boolean secureFieldStatus; | |
private SecureLoggingUtil secureLoggingUtil; | |
public SecureLoggingUtil getSecureLoggingUtil() { | |
return secureLoggingUtil; | |
} | |
public void setSecureLoggingUtil(SecureLoggingUtil secureLoggingUtil) { | |
this.secureLoggingUtil = secureLoggingUtil; | |
} | |
public boolean isSecureFieldStatus() { | |
return secureFieldStatus; | |
} | |
public void setSecureFieldStatus(boolean secureFieldStatus) { | |
this.secureFieldStatus = secureFieldStatus; | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sachinhandiekar.examples.cxf.logging; | |
import java.io.FilterWriter; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.io.StringReader; | |
import java.io.StringWriter; | |
import java.io.Writer; | |
import java.nio.charset.Charset; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
import javax.xml.transform.OutputKeys; | |
import javax.xml.transform.Transformer; | |
import javax.xml.transform.stream.StreamResult; | |
import javax.xml.transform.stream.StreamSource; | |
import org.apache.commons.io.IOUtils; | |
import org.apache.cxf.common.logging.LogUtils; | |
import org.apache.cxf.common.util.StringUtils; | |
import org.apache.cxf.helpers.XMLUtils; | |
import org.apache.cxf.interceptor.Fault; | |
import org.apache.cxf.interceptor.LoggingMessage; | |
import org.apache.cxf.interceptor.LoggingOutInterceptor; | |
import org.apache.cxf.io.CacheAndWriteOutputStream; | |
import org.apache.cxf.io.CachedOutputStream; | |
import org.apache.cxf.io.CachedOutputStreamCallback; | |
import org.apache.cxf.message.Message; | |
import org.apache.cxf.service.model.EndpointInfo; | |
import org.apache.cxf.service.model.InterfaceInfo; | |
public class SensitiveCXFLoggingOutInterceptor extends LoggingOutInterceptor { | |
private static final String LOG_SETUP = LoggingOutInterceptor.class.getName() + ".log-setup"; | |
public void handleMessage(Message message) throws Fault { | |
final OutputStream os = message.getContent(OutputStream.class); | |
final Writer iowriter = message.getContent(Writer.class); | |
if (os == null && iowriter == null) { | |
return; | |
} | |
Logger logger = getMessageLogger(message); | |
if (logger.isLoggable(Level.INFO) || writer != null) { | |
// Write the output while caching it for the log message | |
boolean hasLogged = message.containsKey(LOG_SETUP); | |
if (!hasLogged) { | |
message.put(LOG_SETUP, Boolean.TRUE); | |
if (os != null) { | |
final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os); | |
if (threshold > 0) { | |
newOut.setThreshold(threshold); | |
} | |
message.setContent(OutputStream.class, newOut); | |
newOut.registerCallback(new LoggingCallback(logger, message, os)); | |
} | |
else { | |
message.setContent(Writer.class, new LogWriter(logger, message, iowriter)); | |
} | |
} | |
} | |
} | |
private LoggingMessage setupBuffer(Message message) { | |
String id = (String) message.getExchange().get(LoggingMessage.ID_KEY); | |
if (id == null) { | |
id = LoggingMessage.nextId(); | |
message.getExchange().put(LoggingMessage.ID_KEY, id); | |
} | |
final LoggingMessage buffer = new LoggingMessage("Outbound Message\n---------------------------", id); | |
Integer responseCode = (Integer) message.get(Message.RESPONSE_CODE); | |
if (responseCode != null) { | |
buffer.getResponseCode().append(responseCode); | |
} | |
String encoding = (String) message.get(Message.ENCODING); | |
if (encoding != null) { | |
buffer.getEncoding().append(encoding); | |
} | |
String httpMethod = (String) message.get(Message.HTTP_REQUEST_METHOD); | |
if (httpMethod != null) { | |
buffer.getHttpMethod().append(httpMethod); | |
} | |
String address = (String) message.get(Message.ENDPOINT_ADDRESS); | |
if (address != null) { | |
buffer.getAddress().append(address); | |
} | |
String ct = (String) message.get(Message.CONTENT_TYPE); | |
if (ct != null) { | |
buffer.getContentType().append(ct); | |
} | |
Object headers = message.get(Message.PROTOCOL_HEADERS); | |
if (headers != null) { | |
buffer.getHeader().append(headers); | |
} | |
return buffer; | |
} | |
private class LogWriter extends FilterWriter { | |
StringWriter out2; | |
int count; | |
Logger logger; // NOPMD | |
Message message; | |
public LogWriter(Logger logger, Message message, Writer writer) { | |
super(writer); | |
this.logger = logger; | |
this.message = message; | |
if (!(writer instanceof StringWriter)) { | |
out2 = new StringWriter(); | |
} | |
} | |
public void write(int c) throws IOException { | |
super.write(c); | |
if (out2 != null && count < limit) { | |
out2.write(c); | |
} | |
count++; | |
} | |
public void write(char[] cbuf, int off, int len) throws IOException { | |
super.write(cbuf, off, len); | |
if (out2 != null && count < limit) { | |
out2.write(cbuf, off, len); | |
} | |
count += len; | |
} | |
public void write(String str, int off, int len) throws IOException { | |
super.write(str, off, len); | |
if (out2 != null && count < limit) { | |
out2.write(str, off, len); | |
} | |
count += len; | |
} | |
public void close() throws IOException { | |
LoggingMessage buffer = setupBuffer(message); | |
if (count >= limit) { | |
buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); | |
} | |
StringWriter w2 = out2; | |
if (w2 == null) { | |
w2 = (StringWriter) out; | |
} | |
String ct = (String) message.get(Message.CONTENT_TYPE); | |
try { | |
writePayload(buffer.getPayload(), w2, ct); | |
} | |
catch (Exception ex) { | |
// ignore | |
} | |
log(logger, buffer.toString()); | |
message.setContent(Writer.class, out); | |
super.close(); | |
} | |
} | |
protected String formatLoggingMessage(LoggingMessage buffer) { | |
return buffer.toString(); | |
} | |
class LoggingCallback implements CachedOutputStreamCallback { | |
private final Message message; | |
private final OutputStream origStream; | |
private final Logger logger; // NOPMD | |
public LoggingCallback(final Logger logger, final Message msg, final OutputStream os) { | |
this.logger = logger; | |
this.message = msg; | |
this.origStream = os; | |
} | |
public void onFlush(CachedOutputStream cos) { | |
} | |
public void onClose(CachedOutputStream cos) { | |
LoggingMessage buffer = setupBuffer(message); | |
String ct = (String) message.get(Message.CONTENT_TYPE); | |
if (!isShowBinaryContent() && isBinaryContent(ct)) { | |
buffer.getMessage().append(BINARY_CONTENT_MESSAGE).append('\n'); | |
log(logger, formatLoggingMessage(buffer)); | |
return; | |
} | |
if (cos.getTempFile() == null) { | |
// buffer.append("Outbound Message:\n"); | |
if (cos.size() > limit) { | |
buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); | |
} | |
} | |
else { | |
buffer.getMessage().append("Outbound Message (saved to tmp file):\n"); | |
buffer.getMessage().append("Filename: " + cos.getTempFile().getAbsolutePath() + "\n"); | |
if (cos.size() > limit) { | |
buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); | |
} | |
} | |
try { | |
String encoding = (String) message.get(Message.ENCODING); | |
writePayload(buffer.getPayload(), cos, encoding, ct); | |
} | |
catch (Exception ex) { | |
// ignore | |
} | |
log(logger, formatLoggingMessage(buffer)); | |
try { | |
// empty out the cache | |
cos.lockOutputStream(); | |
cos.resetOut(null, false); | |
} | |
catch (Exception ex) { | |
// ignore | |
} | |
message.setContent(OutputStream.class, origStream); | |
} | |
} | |
Logger getMessageLogger(Message message) { | |
EndpointInfo endpoint = message.getExchange().getEndpoint().getEndpointInfo(); | |
if (endpoint.getService() == null) { | |
return getLogger(); | |
} | |
Logger logger = endpoint.getProperty("MessageLogger", Logger.class); | |
if (logger == null) { | |
String serviceName = endpoint.getService().getName().getLocalPart(); | |
InterfaceInfo iface = endpoint.getService().getInterface(); | |
String portName = endpoint.getName().getLocalPart(); | |
String portTypeName = iface.getName().getLocalPart(); | |
String logName = "org.apache.cxf.services." + serviceName + "." + portName + "." + portTypeName; | |
logger = LogUtils.getL7dLogger(this.getClass(), null, logName); | |
endpoint.setProperty("MessageLogger", logger); | |
} | |
return logger; | |
} | |
protected void writePayload(StringBuilder builder, CachedOutputStream cos, String encoding, String contentType) | |
throws Exception { | |
if (isSecureFieldStatus()) { | |
StringWriter strWriter = new StringWriter(); | |
InputStream inputStream = cos.getInputStream(); | |
IOUtils.copy(inputStream, strWriter, "UTF-8"); | |
String protectedContent = secureLoggingUtil.maskSensitiveInformation(strWriter.toString()); | |
CachedOutputStream ncos = new CachedOutputStream(); | |
ncos.write(protectedContent.toString().getBytes(Charset.forName("UTF-8"))); | |
cos = ncos; | |
} | |
// Just transform the XML message when the cos has content | |
if (isPrettyLogging() | |
&& (contentType != null && contentType.indexOf("xml") >= 0 && contentType.toLowerCase().indexOf( | |
"multipart/related") < 0) && cos.size() > 0) { | |
Transformer serializer = XMLUtils.newTransformer(2); | |
// Setup indenting to "pretty print" | |
serializer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); | |
StringWriter swriter = new StringWriter(); | |
serializer.transform(new StreamSource(cos.getInputStream()), new StreamResult(swriter)); | |
String result = swriter.toString(); | |
if (result.length() < limit || limit == -1) { | |
builder.append(swriter.toString()); | |
} | |
else { | |
builder.append(swriter.toString().substring(0, limit)); | |
} | |
} | |
else { | |
if (StringUtils.isEmpty(encoding)) { | |
cos.writeCacheTo(builder, limit); | |
} | |
else { | |
cos.writeCacheTo(builder, encoding, limit); | |
} | |
} | |
} | |
protected void writePayload(StringBuilder builder, StringWriter stringWriter, String contentType) throws Exception { | |
// Just transform the XML message when the cos has content | |
if (isPrettyLogging() && contentType != null && contentType.indexOf("xml") >= 0 | |
&& stringWriter.getBuffer().length() > 0) { | |
Transformer serializer = XMLUtils.newTransformer(2); | |
// Setup indenting to "pretty print" | |
serializer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); | |
StringWriter swriter = new StringWriter(); | |
serializer.transform(new StreamSource(new StringReader(stringWriter.getBuffer().toString())), | |
new StreamResult(swriter)); | |
String result = swriter.toString(); | |
if (result.length() < limit || limit == -1) { | |
builder.append(swriter.toString()); | |
} | |
else { | |
builder.append(swriter.toString().substring(0, limit)); | |
} | |
} | |
else { | |
StringBuffer buffer = stringWriter.getBuffer(); | |
if (buffer.length() > limit) { | |
builder.append(buffer.subSequence(0, limit)); | |
} | |
else { | |
builder.append(buffer); | |
} | |
} | |
} | |
private boolean secureFieldStatus; | |
private SecureLoggingUtil secureLoggingUtil; | |
public SecureLoggingUtil getSecureLoggingUtil() { | |
return secureLoggingUtil; | |
} | |
public void setSecureLoggingUtil(SecureLoggingUtil secureLoggingUtil) { | |
this.secureLoggingUtil = secureLoggingUtil; | |
} | |
public boolean isSecureFieldStatus() { | |
return secureFieldStatus; | |
} | |
public void setSecureFieldStatus(boolean secureFieldStatus) { | |
this.secureFieldStatus = secureFieldStatus; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
some issues I have noticed in class file name and java file name - pls check SensitiveCXFLoggingInInterceptor.java and class name mentioned

!!