如何在加密前在 Apache CXF 中启用调试日志记录
How to enable debug logging in Apache CXF before encrypting
我已经像这样为我的 WS-Client 启用了调试日志
Client client = ClientProxy.getClient(port);
LoggingInInterceptor loggingInInterceptor = new LoggingInInterceptor();
loggingInInterceptor.setPrettyLogging(true);
LoggingOutInterceptor loggingOutInterceptor = new LoggingOutInterceptor();
loggingOutInterceptor.setPrettyLogging(true);
client.getOutInterceptors().add(loggingOutInterceptor);
client.getInInterceptors().add(loggingInInterceptor);
不幸的是,这会产生如下输出:
[...]
<soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="_fac28258-8b72-4e26-8936-f8ec39d36941">
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-c2e3310c-c15c-44f9-b458-d2f84bbad79f" Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
[...]
<xenc:CipherData>
<xenc:CipherValue>YSeTqiVf7/yDrgG8Vp/eUp5lbl4pJpFvkyv4spNKRmoD+0j1XmI4YIWhiFldlBwRqsaAhSDHR0p9nj6Hq37elnXWj2PAFvAqBprh2sxN9q06cWEmIOo8yvC/te41GyVTWGwe0qnS7Q3J79p5LbnUBFZl3pHzAVJDAYG4NMeJE6iAw1gwVIYEraS495d09oYBEV29C9Q1RsHO0xIeg2pzuZv0epm8X5zTCJidGe7sEn0Ko9u+3uLonAqMYgFUeKX+CwTq8ZDCe1LJcrp41S/n7HEj2HdrnVrQ0U+ZqamBUF3J9w+buH26YFuIF61UAv+xedual+RpgxMj+kKqMeIbhcZfxoaVv7PjsIbyDNNwUk/TVfxycF9KosQzWllImmAV514roVo3WzaFHUzcqX+bKpcfYbQaH4E0at+NV4mBUymY6sQar9QskSH5yYUgocDwR5/K45xtxiVDldWKtAOjERhIiWmIMvVLsDY6s43XLH5rtHuRpSOPLKuugtFLvBc/zo1cLkMvzcpCzwzMK/yTTA+/S5Sm5aVMnrASegFd/hsvfwjNgHVnAPTjVAcRe8FlxaT51XyUBWS/LGQGLH5ZhKBLJqQ4TOD+Gj6VfvREDVBIDmmnoWL/Sa5NdcVQ03WrUbq9x71C179p0Kas8u950iWO0lq/bFqVlcZKegSW0/wQ0OLR7C4tBk06XoM4UhT2MJa/4aFUhFuo4PZhK4GbdSLwrO0ECuNPfLF0Fae4xLNglSCGFhfBZ4FlfqqPvnJOB4S24r7sTXamjPyS49m70yIn/mk/vFgc5fzcrMwMwMweQm/tjKYT4eJIkNqpW6M3QcACNkJUyrOjl2mf0lDyrkEcZPFr6v+Fae/5B70H48kUgRDFp6ozsZiP+XiooVfKisskBNrKZNcS34101VUCOC9opZnNO5Tr9XvLYKN9lQQ=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
如果我需要澄清传输的业务数据,这并没有太大帮助。
有没有办法在加密之前获取传出 SOAP 信封并在解密之后分别获取传入 SOAP 信封?
加密发生在输出链的 PRE_PROTOCOL 阶段。如果要记录清晰的消息,则必须将日志记录拦截器设置为在此阶段之前的阶段。
您可以在拦截器构造函数中传递阶段。
CXF 阶段文档:http://cxf.apache.org/docs/interceptors.html
我能够通过像这样实现我自己的 LogginInterceptor 来生成我想要的日志记录:
public class CleartextLogger extends AbstractSoapInterceptor {
private static final String LOG_SETUP = CleartextLogger.class.getName() + ".log-setup";
private Logger logger;
public CleartextLogger(Logger logger) {
super(Phase.POST_PROTOCOL);
this.logger = logger;
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
try {
boolean logged = message.containsKey(LOG_SETUP);
if (!logged) {
message.put(LOG_SETUP, Boolean.TRUE);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
SOAPMessage smsg = message.getContent(SOAPMessage.class);
if(smsg != null) {
smsg.writeTo(bout);
log(bout.toString());
} else {
logger.warn("Es gab keinen verschlüsselten Inhalt zu loggen");
}
}
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void log(String xml) {
StringReader in = new StringReader(xml);
StringWriter swriter = new StringWriter();
XMLStreamWriter xwriter = StaxUtils.createXMLStreamWriter(swriter);
xwriter = new PrettyPrintXMLStreamWriter(xwriter, 2);
try {
StaxUtils.copy(new StreamSource(in), xwriter);
} catch (XMLStreamException xse) {
//ignore
} finally {
try {
xwriter.flush();
xwriter.close();
} catch (XMLStreamException xse2) {
//ignore
}
in.close();
}
String result = swriter.toString();
logger.debug(result);
}
}
并在拦截器链中为 outgoing/incoming 日志添加此拦截器:
CleartextLogger clearOutputLogger = new CleartextLogger(logger);
CleartextLogger clearInputLogger = new CleartextLogger(logger);
client.getOutInterceptors().add(clearOutputLogger);
client.getInInterceptors().add(clearInputLogger);
logger
对象是 org.apache.log4j.Logger.
的实例
此记录器在加密前和解密后记录。
我已经像这样为我的 WS-Client 启用了调试日志
Client client = ClientProxy.getClient(port);
LoggingInInterceptor loggingInInterceptor = new LoggingInInterceptor();
loggingInInterceptor.setPrettyLogging(true);
LoggingOutInterceptor loggingOutInterceptor = new LoggingOutInterceptor();
loggingOutInterceptor.setPrettyLogging(true);
client.getOutInterceptors().add(loggingOutInterceptor);
client.getInInterceptors().add(loggingInInterceptor);
不幸的是,这会产生如下输出:
[...]
<soap:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="_fac28258-8b72-4e26-8936-f8ec39d36941">
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-c2e3310c-c15c-44f9-b458-d2f84bbad79f" Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
[...]
<xenc:CipherData>
<xenc:CipherValue>YSeTqiVf7/yDrgG8Vp/eUp5lbl4pJpFvkyv4spNKRmoD+0j1XmI4YIWhiFldlBwRqsaAhSDHR0p9nj6Hq37elnXWj2PAFvAqBprh2sxN9q06cWEmIOo8yvC/te41GyVTWGwe0qnS7Q3J79p5LbnUBFZl3pHzAVJDAYG4NMeJE6iAw1gwVIYEraS495d09oYBEV29C9Q1RsHO0xIeg2pzuZv0epm8X5zTCJidGe7sEn0Ko9u+3uLonAqMYgFUeKX+CwTq8ZDCe1LJcrp41S/n7HEj2HdrnVrQ0U+ZqamBUF3J9w+buH26YFuIF61UAv+xedual+RpgxMj+kKqMeIbhcZfxoaVv7PjsIbyDNNwUk/TVfxycF9KosQzWllImmAV514roVo3WzaFHUzcqX+bKpcfYbQaH4E0at+NV4mBUymY6sQar9QskSH5yYUgocDwR5/K45xtxiVDldWKtAOjERhIiWmIMvVLsDY6s43XLH5rtHuRpSOPLKuugtFLvBc/zo1cLkMvzcpCzwzMK/yTTA+/S5Sm5aVMnrASegFd/hsvfwjNgHVnAPTjVAcRe8FlxaT51XyUBWS/LGQGLH5ZhKBLJqQ4TOD+Gj6VfvREDVBIDmmnoWL/Sa5NdcVQ03WrUbq9x71C179p0Kas8u950iWO0lq/bFqVlcZKegSW0/wQ0OLR7C4tBk06XoM4UhT2MJa/4aFUhFuo4PZhK4GbdSLwrO0ECuNPfLF0Fae4xLNglSCGFhfBZ4FlfqqPvnJOB4S24r7sTXamjPyS49m70yIn/mk/vFgc5fzcrMwMwMweQm/tjKYT4eJIkNqpW6M3QcACNkJUyrOjl2mf0lDyrkEcZPFr6v+Fae/5B70H48kUgRDFp6ozsZiP+XiooVfKisskBNrKZNcS34101VUCOC9opZnNO5Tr9XvLYKN9lQQ=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
如果我需要澄清传输的业务数据,这并没有太大帮助。
有没有办法在加密之前获取传出 SOAP 信封并在解密之后分别获取传入 SOAP 信封?
加密发生在输出链的 PRE_PROTOCOL 阶段。如果要记录清晰的消息,则必须将日志记录拦截器设置为在此阶段之前的阶段。 您可以在拦截器构造函数中传递阶段。 CXF 阶段文档:http://cxf.apache.org/docs/interceptors.html
我能够通过像这样实现我自己的 LogginInterceptor 来生成我想要的日志记录:
public class CleartextLogger extends AbstractSoapInterceptor {
private static final String LOG_SETUP = CleartextLogger.class.getName() + ".log-setup";
private Logger logger;
public CleartextLogger(Logger logger) {
super(Phase.POST_PROTOCOL);
this.logger = logger;
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
try {
boolean logged = message.containsKey(LOG_SETUP);
if (!logged) {
message.put(LOG_SETUP, Boolean.TRUE);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
SOAPMessage smsg = message.getContent(SOAPMessage.class);
if(smsg != null) {
smsg.writeTo(bout);
log(bout.toString());
} else {
logger.warn("Es gab keinen verschlüsselten Inhalt zu loggen");
}
}
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void log(String xml) {
StringReader in = new StringReader(xml);
StringWriter swriter = new StringWriter();
XMLStreamWriter xwriter = StaxUtils.createXMLStreamWriter(swriter);
xwriter = new PrettyPrintXMLStreamWriter(xwriter, 2);
try {
StaxUtils.copy(new StreamSource(in), xwriter);
} catch (XMLStreamException xse) {
//ignore
} finally {
try {
xwriter.flush();
xwriter.close();
} catch (XMLStreamException xse2) {
//ignore
}
in.close();
}
String result = swriter.toString();
logger.debug(result);
}
}
并在拦截器链中为 outgoing/incoming 日志添加此拦截器:
CleartextLogger clearOutputLogger = new CleartextLogger(logger);
CleartextLogger clearInputLogger = new CleartextLogger(logger);
client.getOutInterceptors().add(clearOutputLogger);
client.getInInterceptors().add(clearInputLogger);
logger
对象是 org.apache.log4j.Logger.
此记录器在加密前和解密后记录。