You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Alejandro <al...@gmail.com> on 2011/04/15 17:18:40 UTC

Log SoapMessage After WSS4J

Hi, I need to log the message after processing the WSS4JInInterceptor. The
actual LoggingInInterceptor works as the first interceptor in the chain so
it logs the message with all security headers and with the encrypted
content.
Is any way to log the plain message?

Regards

--
View this message in context: http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4305812.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Log SoapMessage After WSS4J

Posted by Aki Yoshida <el...@googlemail.com>.
Hi,
I think you should be able to see the decrypted content if you
serialize the SOAPMessage object (simply using its writeTo method)
after the wss4j's inbound processing, as Dan suggested earlier in this
thread.

The serialized message contains tons of wss artifacts and it may
appear to be still encrypted but it is decrypted and the decrypted
content should be present in the message.

If this is really not the case, you should make sure that your
interceptor is placed at the right phase. As the wss4j inbound
processing is taking place at phase PRE_PROTOCOL, you can place your
own logger interceptor at USER_PROTOCOL or POST_PROTOCOL that follows
this phase.

regards, aki
2011/4/19 Alejandro <al...@gmail.com>:
> Sorry doesn't work means that log the message encrypted.
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4314128.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>

Re: Log SoapMessage After WSS4J

Posted by Alejandro <al...@gmail.com>.
Sorry doesn't work means that log the message encrypted.

--
View this message in context: http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4314128.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Log SoapMessage After WSS4J

Posted by Daniel Kulp <dk...@apache.org>.
On Tuesday 19 April 2011 1:07:19 PM Alejandro wrote:
> Hi, I'd used that you said it's doesn't works, I put the code that I used.

Can you define "doesn't work"? Does it not log anything?   Is what is logged 
wrong?   etc...

Thinking about, I think I may have gotten confused.  You want to log BEFORE 
the wss4j stuff, right?  In that case, you likely can just stick it in the 
USER_PROTOCOL phase and not use any before/after things.


Dan


> 
> 
> public class LoggingOutInterceptor extends AbstractPhaseInterceptor
> {
> 	private static final String LOG_SETUP =
> LoggingOutInterceptor.class.getName() + ".log-setup";
> 
> 	private static final Logger LOG =
> LogUtils.getL7dLogger(LoggingOutInterceptor.class);
> 
> 	private int limit = 100 * 1024;
> 	private PrintWriter writer;
> 
> 	public LoggingOutInterceptor(String phase)
> 	{
> 		super(phase);
> 		addBefore(SAAJOutEndingInterceptor.class.getName());
> 	}
> 
> 	public LoggingOutInterceptor()
> 	{
> 		super(Phase.PRE_PROTOCOL_ENDING);
> 		addBefore(SAAJOutEndingInterceptor.class.getName());
> 	}
> 
> 	public LoggingOutInterceptor(int lim)
> 	{
> 		this();
> 		limit = lim;
> 	}
> 
> 	public LoggingOutInterceptor(PrintWriter w)
> 	{
> 		this();
> 		this.writer = w;
> 	}
> 
> 	public void setLimit(int lim)
> 	{
> 		limit = lim;
> 	}
> 
> 	public int getLimit()
> 	{
> 		return limit;
> 	}
> 
> 	public void handleMessage(Message message) throws Fault
> 	{
> 		final CachedOutputStream os = new CachedOutputStream();
> 		SOAPMessage is = message.getContent(SOAPMessage.class);
> 		if (is == null)
> 		{
> 			return;
> 		}
> 
> 		try
> 		{
> 			is.writeTo(os);
> 		}
> 		catch (SOAPException e)
> 		{
> 			return;
> 		}
> 		catch (IOException e)
> 		{
> 			return;
> 		}
> 
> 		if (LOG.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);
> 				final CacheAndWriteOutputStream newOut = new
> CacheAndWriteOutputStream(os);
> 				message.setContent(OutputStream.class, newOut);
> 				newOut.registerCallback(new LoggingCallback(message, os));
> 			}
> 		}
> 	}
> 
> 	/**
> 	 * Transform the string before display. The implementation in this class
> 	 * does nothing. Override this method if you want to change the contents
> of * the logged message before it is delivered to the output. For example,
> you
> 	 * can use this to masking out sensitive information.
> 	 *
> 	 * @param originalLogString
> 	 *            the raw log message.
> 	 * @return transformed data
> 	 */
> 	protected String transform(String originalLogString)
> 	{
> 		return originalLogString;
> 	}
> 
> 	class LoggingCallback implements CachedOutputStreamCallback
> 	{
> 
> 		private final Message message;
> 		private final OutputStream origStream;
> 
> 		public LoggingCallback(final Message msg, final OutputStream os)
> 		{
> 			this.message = msg;
> 			this.origStream = os;
> 		}
> 
> 		public void onFlush(CachedOutputStream cos)
> 		{
> 
> 		}
> 
> 		public void onClose(CachedOutputStream cos)
> 		{
> 			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 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);
> 			}
> 
> 			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
> 			{
> 				cos.writeCacheTo(buffer.getPayload(), limit);
> 			}
> 			catch (Exception ex)
> 			{
> 				// ignore
> 			}
> 
> 			if (writer != null)
> 			{
> 				writer.println(transform(buffer.toString()));
> 			}
> 			else if (LOG.isLoggable(Level.INFO))
> 			{
> 				LOG.info(transform(buffer.toString()));
> 			}
> 			try
> 			{
> 				// empty out the cache
> 				cos.lockOutputStream();
> 				cos.resetOut(null, false);
> 			}
> 			catch (Exception ex)
> 			{
> 				// ignore
> 			}
> 			message.setContent(OutputStream.class, origStream);
> 		}
> 	}
> 
> }
> 
> Regards
> 
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4313
> 815.html Sent from the cxf-user mailing list archive at Nabble.com.

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com

Re: Log SoapMessage After WSS4J

Posted by Alejandro <al...@gmail.com>.
Hi, I'd used that you said it's doesn't works, I put the code that I used.


public class LoggingOutInterceptor extends AbstractPhaseInterceptor
{
	private static final String LOG_SETUP =
LoggingOutInterceptor.class.getName() + ".log-setup";

	private static final Logger LOG =
LogUtils.getL7dLogger(LoggingOutInterceptor.class);

	private int limit = 100 * 1024;
	private PrintWriter writer;

	public LoggingOutInterceptor(String phase)
	{
		super(phase);
		addBefore(SAAJOutEndingInterceptor.class.getName());
	}

	public LoggingOutInterceptor()
	{
		super(Phase.PRE_PROTOCOL_ENDING);
		addBefore(SAAJOutEndingInterceptor.class.getName());
	}

	public LoggingOutInterceptor(int lim)
	{
		this();
		limit = lim;
	}

	public LoggingOutInterceptor(PrintWriter w)
	{
		this();
		this.writer = w;
	}

	public void setLimit(int lim)
	{
		limit = lim;
	}

	public int getLimit()
	{
		return limit;
	}

	public void handleMessage(Message message) throws Fault
	{
		final CachedOutputStream os = new CachedOutputStream();
		SOAPMessage is = message.getContent(SOAPMessage.class);
		if (is == null)
		{
			return;
		}
		
		try
		{
			is.writeTo(os);
		}
		catch (SOAPException e)
		{
			return;
		}
		catch (IOException e)
		{
			return;
		}

		if (LOG.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);
				final CacheAndWriteOutputStream newOut = new
CacheAndWriteOutputStream(os);
				message.setContent(OutputStream.class, newOut);
				newOut.registerCallback(new LoggingCallback(message, os));
			}
		}
	}

	/**
	 * Transform the string before display. The implementation in this class
	 * does nothing. Override this method if you want to change the contents of
	 * the logged message before it is delivered to the output. For example,
you
	 * can use this to masking out sensitive information.
	 * 
	 * @param originalLogString
	 *            the raw log message.
	 * @return transformed data
	 */
	protected String transform(String originalLogString)
	{
		return originalLogString;
	}

	class LoggingCallback implements CachedOutputStreamCallback
	{

		private final Message message;
		private final OutputStream origStream;

		public LoggingCallback(final Message msg, final OutputStream os)
		{
			this.message = msg;
			this.origStream = os;
		}

		public void onFlush(CachedOutputStream cos)
		{

		}

		public void onClose(CachedOutputStream cos)
		{
			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 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);
			}

			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
			{
				cos.writeCacheTo(buffer.getPayload(), limit);
			}
			catch (Exception ex)
			{
				// ignore
			}

			if (writer != null)
			{
				writer.println(transform(buffer.toString()));
			}
			else if (LOG.isLoggable(Level.INFO))
			{
				LOG.info(transform(buffer.toString()));
			}
			try
			{
				// empty out the cache
				cos.lockOutputStream();
				cos.resetOut(null, false);
			}
			catch (Exception ex)
			{
				// ignore
			}
			message.setContent(OutputStream.class, origStream);
		}
	}

}

Regards

--
View this message in context: http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4313815.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Log SoapMessage After WSS4J

Posted by Daniel Kulp <dk...@apache.org>.
On Monday 18 April 2011 2:04:11 PM Alejandro wrote:
> Thanks Daniel, this code works fine.
> 
> Now I need to do the same Interceptor in the out chain, which PHASE I must
> used? and the must be after and before which interceptor?

It's likely the PRE_PROTOCOL_ENDING phase with a before of 
SAAJOutEndingInterceptor.class.getName().

Dan



> 
> Regards.
> 
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4311
> 372.html Sent from the cxf-user mailing list archive at Nabble.com.

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com

Re: Log SoapMessage After WSS4J

Posted by Alejandro <al...@gmail.com>.
Thanks Daniel, this code works fine.

Now I need to do the same Interceptor in the out chain, which PHASE I must
used? and the must be after and before which interceptor?

Regards.

--
View this message in context: http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4311372.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: Log SoapMessage After WSS4J

Posted by Daniel Kulp <dk...@apache.org>.
On Friday 15 April 2011 11:18:40 AM Alejandro wrote:
> Hi, I need to log the message after processing the WSS4JInInterceptor. The
> actual LoggingInInterceptor works as the first interceptor in the chain so
> it logs the message with all security headers and with the encrypted
> content.
> Is any way to log the plain message?

The Logging interceptor we have work at the stream level.  Thus, they won't 
work after the SAAJ stuff (which is what the WSS4J interceptors would result 
in).    However, you should be able to create your own interceptor relatively 
easily that would do something like:

SOAPMessage smsg = msg.getContent(SOAPMessage.class);
smsg.writeTo(byteArrayOutputStream);
System.out.println(byteArrayOutputStream);

or similar.

Dan




> 
> Regards
> 
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/Log-SoapMessage-After-WSS4J-tp4305812p4305
> 812.html Sent from the cxf-user mailing list archive at Nabble.com.

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog
Talend - http://www.talend.com