java - CXF Logging request & response with content filtering or masking soap fields -


i log incoming requests & responses particular endpoint, content filtering. i.e. when have request that:

<soap:envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"> <soap:body>   <m:processphoto xmlns:m="http://www.w3schools.com/photos">     <m:name>apples</m:name>     <m:description>photo apples in it</m:description>     <!-- large encoded binary below -->     <m:photo>anvzdcbhihjhbmrvbsb0zxh0dqpqdxn0igegcmfuzg9tihrlehqncmp1c3qgysbyyw5kb20gdgv4da0kanvzdcbhihjhbmrvbsb0zxh0dqpqdxn0igegcmfuzg9tihrlehqncmp1c3qgysbyyw5kb20gdgv4da0kanvzdcbhihjhbmrvbsb0zxh0dqp3b3csigkgzglkbid0ihrob3vnahqgdghhdcbhbnlvbmugd291bgqgymugaw50zxjlc3rlzcbpbibkzwnvzgluzyb0aglzlibjb25ncmf0cye=</m:photo>   </m:processphoto> </soap:body> </soap:envelope> 

i filter it, looks in logs that

<soap:envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"> <soap:body>   <m:processphoto xmlns:m="http://www.w3schools.com/photos">     <m:name>apples</m:name>     <m:description>photo apples in it</m:description>     <m:photo>hidden</m:photo>   </m:processphoto> </soap:body> </soap:envelope> 

or removed m:photo element.

i found cxf has loggingininterceptor , loggingoutinterceptor , write own interceptors that. work do, question is: know better, out of box solution?

i had similar problem, needed mask passwords in input request. made small change existing loggininterceptor , overridden format method , added method mask password. here example

public class customlogininterceptor extends loggingininterceptor {      @override     protected string formatloggingmessage(loggingmessage loggingmessage) {          string str = loggingmessage.tostring();          string output = maskpasswords(str);         return(output);     }       private string maskpasswords(string str) {                  final string[] keys = { "password", "passwords" };                 (string key : keys) {                     int beginindex = 0;                     int lastindex = -1;                     boolean emptypass = false;                     while (beginindex != -1                             && (beginindex = stringutils.indexofignorecase(str, key,                                     beginindex)) > 0) {                          beginindex = stringutils.indexof(str, ">", beginindex);                         if (beginindex != -1) {                             char ch = str.charat(beginindex - 1);                             if (ch == '/') {                                 emptypass = true;                             }                             if (!emptypass) {                                 lastindex = stringutils.indexof(str, "<", beginindex);                                 if (lastindex != -1) {                                     string overlay = "*";                                     string str2 = stringutils.substring(str,                                             beginindex + 1, lastindex);                                     if (str2 != null && str2.length() > 1) {                                         overlay = stringutils.rightpad(overlay,                                                 str2.length(), "*");                                         str = stringutils.overlay(str, overlay,                                                 beginindex + 1, lastindex);                                     }                                 }                             }                             if (emptypass) {                                 emptypass = false;                                 lastindex = beginindex + 1;                             } else {                                 if (lastindex != -1) {                                     lastindex = stringutils                                             .indexof(str, ">", lastindex);                                 }                             }                         }                         beginindex = lastindex;                     }                 }                 return str;              }  } 

and added custtom cxf logging bean in cxf-bean.xml

<bean id="kpininterceptor" class="com.kp.util.customlogininterceptor" />  <cxf:bus>         <cxf:ininterceptors>             <ref bean="kpininterceptor" />         </cxf:ininterceptors>         <cxf:infaultinterceptors>             <ref bean="kpininterceptor" />         </cxf:infaultinterceptors> </cxf:bus> 

note i've used apache commons-lang3 jar string manipulation. can use response well


update

using patterns , making keys configurable using properties.

interceptor

public class customlogininterceptor extends loggingininterceptor {      private static final string mask_pattern = "<\\s*{}\\s*>(.*)</\\s*{}\\s*>|<\\s*name\\s*>\\s*{}\\s*</\\s*name\\s*>\\s*<\\s*value\\s*>(.*)<";      private pattern pattern;      private string[] keys;      public void init() {         stringbuilder builder = new stringbuilder();         (string str : keys) {             builder.append(mask_pattern.replace("{}", str));             builder.append("|");         }         builder.setlength(builder.length()-1);         pattern = pattern.compile(builder.tostring(), pattern.case_insensitive | pattern.multiline);     }      public void setkeys(string[] keys) {         this.keys = keys;     }       @override     protected string formatloggingmessage(loggingmessage loggingmessage) {          string output = maskpasswords(loggingmessage.tostring());         return(output);     }       private string maskpasswords(string str) {          matcher matcher = pattern.matcher(str);         final stringbuilder builder = new stringbuilder(str);         while (matcher.find()) {              int group = 1;             while (group <= matcher.groupcount()) {                 if (matcher.group(group) != null) {                     (int = matcher.start(group); < matcher.end(group); i++) {                         builder.setcharat(i, '*');                     }                 }                 group++;             }         }         return builder.tostring();      }  } 

bean creation

<bean id="kpininterceptor" class="com.kp.util.customlogininterceptor" init-method="init">     <property name="keys">         <array value-type="java.lang.string">             <value>password</value>             <value>accountid</value>         </array>     </property> </bean> 

sample input

<?xml version="1.0" encoding="utf-8"?> <test>     <hello>adffas</hello>     <vsdsd>dfsdf</vsdsd>     <password>sdfsfs</password>     <sdfsfsf>sdfsfsf</sdfsfsf>     <password>3434</password>     <name>password</name>     <value>sdfsfs</value>     <password />     <name>password</name>     <value />     <accountid>123456</accountid>     <hello>         <inner1>             <password>                 <password>sdfsfs</password>             </password>         </inner>     </hello> </test> 

and output

<?xml version="1.0" encoding="utf-8"?> <test>     <hello>adffas</hello>     <vsdsd>dfsdf</vsdsd>     <password>******</password>     <sdfsfsf>sdfsfsf</sdfsfsf>     <password>****</password>     <name>password</name>     <value>******</value>     <password />     <name>password</name>     <value />     <accountid>******</accountid>     <hello>         <inner1>             <password>                 <password>******</password>             </password>         </inner>     </hello> </test> 

Comments

Popular posts from this blog

c++ - How to add Crypto++ library to Qt project -

jQuery Mobile app not scrolling in Firefox -

How to use vim as editor in Matlab GUI -