Как включить ведение журнала отладки в Apache CXF перед шифрованием

#java #logging #cxf #ws-security

#java #ведение журнала #cxf #ws-безопасность

Вопрос:

Я уже включил журналы отладки для моего WS-клиента следующим образом

 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-конверт после расшифровки?

Комментарии:

1. Спасибо за фрагмент журнала на стороне клиента, я не смог найти его в документации CXF.

2. Вы случайно нашли aswer?

3. ДА. Пожалуйста, посмотрите мой собственный ответ, который я только что добавил в эту тему

Ответ №1:

Я смог создать желаемое ведение журнала, реализовав свой собственный 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);
    }
}
  

И добавьте этот перехватчик для исходящих / входящих журналов в цепочки перехватчиков:

 CleartextLogger clearOutputLogger = new CleartextLogger(logger);
CleartextLogger clearInputLogger = new CleartextLogger(logger);
client.getOutInterceptors().add(clearOutputLogger);
client.getInInterceptors().add(clearInputLogger);
  

logger Объект является экземпляром org.apache.log4j.Регистратор.

Этот регистратор ведет журнал до шифрования и после дешифрования.

Комментарии:

1. Это работает до шифрования, но не в том случае, если мы хотим зарегистрировать шаг после подписи. Знаете ли вы, как это сделать после подписи и перед шифрованием?

2. Я не уверен, что это возможно. Разве сборка подписи не основана на зашифрованном содержимом?

Ответ №2:

Шифрование происходит на этапе PRE_PROTOCOL для цепочки вывода. Вы должны установить перехватчик ведения журнала на фазу, предшествующую этой, если вы хотите регистрировать четкие сообщения. Вы можете передать фазу в конструкторе перехватчика. Документ фазы CXF: http://cxf.apache.org/docs/interceptors.html

Комментарии:

1. Если я изменю свой LoggingOutInterceptor таким new LoggingOutInterceptor(Phase.PRE_PROTOCOL) образом, единственным выходом для моего исходящего сообщения будет следующее: ID: 1 Address: https://[...] Encoding: UTF-8 Http-Method: POST Content-Type: text/xml Headers: {Accept=[*/*], SOAPAction=["http://tempuri.org/IServiceCustomer/InsertCustomer"]}