What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

Snowball RC
Hi,

I am trying to implement a custom Interceptor to have a global custom "security" logger in my web app.

The target is to log all the datas sended to the server during update, save, delete etc... to have a custom logger for security reasons.

In case of GET and POST (query string param or form data without json object) :
HttpParameters httpParameters = ActionContext.getContext().getParameters();
works fine.

But in case of json params in POST (request payload) the previous code doesn't works
when the params is serialize via : JSON.stringify(...)

code sample:
jQuery.ajax({
        type: 'POST',
        url: url,
        data: JSON.stringify(data),
        dataType: 'json',
        async: false ,
        contentType: 'application/json; charset=utf-8',
        success: function(){
                 self.load();
        },
        error: function(data) {
                 if (data.responseText) {
                         var error = JSON.parse(data.responseText);
                 }
        }

My custom Interceptor is added at the end of my stack after the json interceptor like this :
        <interceptor-ref name="json">
            <param name="contentType">application/json</param>
        </interceptor-ref>
        <interceptor-ref name="commonSecurityLogger"/>
</interceptor-stack>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

Christoph Nenning
Hi,

AFAIK that is defined in servlet spec. Only parameters with content-type "
application/x-www-form-urlencoded" are made available via getParameters().
The struts method you mentioned just forwards to according method of
servlet api.

Your json data can only be read by consuming request inputstream. If you
do so in your interceptor it is not available anymore to your actions (or
struts json interceptor) so you must rewrite them, too.

Regards,
Christoph



> From: "Snowball RC" <[hidden email]>
> To: <[hidden email]>,
> Date: 23.03.2017 11:28
> Subject: What is the best way to get all JSON params in custom
> Interceptor to log them all in a custom logger ?
>
> Hi,
>
> I am trying to implement a custom Interceptor to have a global
> custom "security" logger in my web app.
>
> The target is to log all the datas sended to the server during
> update, save, delete etc... to have a custom logger for security
reasons.
>
> In case of GET and POST (query string param or form data without
> json object) :
> HttpParameters httpParameters =
ActionContext.getContext().getParameters();

> works fine.
>
> But in case of json params in POST (request payload) the previous
> code doesn't works
> when the params is serialize via : JSON.stringify(...)
>
> code sample:
> jQuery.ajax({
>    type: 'POST',
>    url: url,
>    data: JSON.stringify(data),
>    dataType: 'json',
>    async: false ,
>    contentType: 'application/json; charset=utf-8',
>    success: function(){
>        self.load();
>    },
>    error: function(data) {
>        if (data.responseText) {
>           var error = JSON.parse(data.responseText);
>        }
>    }
>
> My custom Interceptor is added at the end of my stack after the json
> interceptor like this :
>         <interceptor-ref name="json">
>               <param name="contentType">application/json</param>
>           </interceptor-ref>
>           <interceptor-ref name="commonSecurityLogger"/>
> </interceptor-stack>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>

This Email was scanned by Sophos Anti Virus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

Snowball RC


On 2017-03-23 14:04 (+0100), Christoph Nenning <[hidden email]> wrote:

> Hi,
>
> AFAIK that is defined in servlet spec. Only parameters with content-type "
> application/x-www-form-urlencoded" are made available via getParameters().
> The struts method you mentioned just forwards to according method of
> servlet api.
>
> Your json data can only be read by consuming request inputstream. If you
> do so in your interceptor it is not available anymore to your actions (or
> struts json interceptor) so you must rewrite them, too.
>
> Regards,
> Christoph
>
>
>
> > From: "Snowball RC" <[hidden email]>
> > To: <[hidden email]>,
> > Date: 23.03.2017 11:28
> > Subject: What is the best way to get all JSON params in custom
> > Interceptor to log them all in a custom logger ?
> >
> > Hi,
> >
> > I am trying to implement a custom Interceptor to have a global
> > custom "security" logger in my web app.
> >
> > The target is to log all the datas sended to the server during
> > update, save, delete etc... to have a custom logger for security
> reasons.
> >
> > In case of GET and POST (query string param or form data without
> > json object) :
> > HttpParameters httpParameters =
> ActionContext.getContext().getParameters();
> > works fine.
> >
> > But in case of json params in POST (request payload) the previous
> > code doesn't works
> > when the params is serialize via : JSON.stringify(...)
> >
> > code sample:
> > jQuery.ajax({
> >    type: 'POST',
> >    url: url,
> >    data: JSON.stringify(data),
> >    dataType: 'json',
> >    async: false ,
> >    contentType: 'application/json; charset=utf-8',
> >    success: function(){
> >        self.load();
> >    },
> >    error: function(data) {
> >        if (data.responseText) {
> >           var error = JSON.parse(data.responseText);
> >        }
> >    }
> >
> > My custom Interceptor is added at the end of my stack after the json
> > interceptor like this :
> >         <interceptor-ref name="json">
> >               <param name="contentType">application/json</param>
> >           </interceptor-ref>
> >           <interceptor-ref name="commonSecurityLogger"/>
> > </interceptor-stack>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
>
> This Email was scanned by Sophos Anti Virus
>
You are right I have tried to use "request.getReader()" and after the json object was not available anymore.
How can I rewrite them ? Should I do the same like in JSONInterceptor ?

Regards,


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

Christoph Nenning
> <[hidden email]> wrote:
> > Hi,
> >
> > AFAIK that is defined in servlet spec. Only parameters with
content-type "
> > application/x-www-form-urlencoded" are made available via
getParameters().
> > The struts method you mentioned just forwards to according method of
> > servlet api.
> >
> > Your json data can only be read by consuming request inputstream. If
you
> > do so in your interceptor it is not available anymore to your actions
(or

> > struts json interceptor) so you must rewrite them, too.
> >
> > Regards,
> > Christoph
> >
> >
> >
> > > From: "Snowball RC" <[hidden email]>
> > > To: <[hidden email]>,
> > > Date: 23.03.2017 11:28
> > > Subject: What is the best way to get all JSON params in custom
> > > Interceptor to log them all in a custom logger ?
> > >
> > > Hi,
> > >
> > > I am trying to implement a custom Interceptor to have a global
> > > custom "security" logger in my web app.
> > >
> > > The target is to log all the datas sended to the server during
> > > update, save, delete etc... to have a custom logger for security
> > reasons.
> > >
> > > In case of GET and POST (query string param or form data without
> > > json object) :
> > > HttpParameters httpParameters =
> > ActionContext.getContext().getParameters();
> > > works fine.
> > >
> > > But in case of json params in POST (request payload) the previous
> > > code doesn't works
> > > when the params is serialize via : JSON.stringify(...)
> > >
> > > code sample:
> > > jQuery.ajax({
> > >    type: 'POST',
> > >    url: url,
> > >    data: JSON.stringify(data),
> > >    dataType: 'json',
> > >    async: false ,
> > >    contentType: 'application/json; charset=utf-8',
> > >    success: function(){
> > >        self.load();
> > >    },
> > >    error: function(data) {
> > >        if (data.responseText) {
> > >           var error = JSON.parse(data.responseText);
> > >        }
> > >    }
> > >
> > > My custom Interceptor is added at the end of my stack after the json
> > > interceptor like this :
> > >         <interceptor-ref name="json">
> > >               <param name="contentType">application/json</param>
> > >           </interceptor-ref>
> > >           <interceptor-ref name="commonSecurityLogger"/>
> > > </interceptor-stack>
> > >
> > >
> > >
---------------------------------------------------------------------

> > > To unsubscribe, e-mail: [hidden email]
> > > For additional commands, e-mail: [hidden email]
> > >
> >
> > This Email was scanned by Sophos Anti Virus
> >
> You are right I have tried to use "request.getReader()" and after
> the json object was not available anymore.
> How can I rewrite them ? Should I do the same like in JSONInterceptor ?
>


Well, when your interceptor reads the inputsream it has to preserve data
in memory in some way and your actions must read it from there.

You can try to copy the inputstream to a byte array first (by using
ByteArrayOutputStream) and wrap request.getInputStream() with a
ByteArrayInputStream pointing to same byte array. Of course that will
cause issues if your users upload large amount of data.


Regards,
Christoph

This Email was scanned by Sophos Anti Virus
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

Snowball RC


On 2017-03-23 14:23 (+0100), Christoph Nenning <[hidden email]> wrote:

> > <[hidden email]> wrote:
> > > Hi,
> > >
> > > AFAIK that is defined in servlet spec. Only parameters with
> content-type "
> > > application/x-www-form-urlencoded" are made available via
> getParameters().
> > > The struts method you mentioned just forwards to according method of
> > > servlet api.
> > >
> > > Your json data can only be read by consuming request inputstream. If
> you
> > > do so in your interceptor it is not available anymore to your actions
> (or
> > > struts json interceptor) so you must rewrite them, too.
> > >
> > > Regards,
> > > Christoph
> > >
> > >
> > >
> > > > From: "Snowball RC" <[hidden email]>
> > > > To: <[hidden email]>,
> > > > Date: 23.03.2017 11:28
> > > > Subject: What is the best way to get all JSON params in custom
> > > > Interceptor to log them all in a custom logger ?
> > > >
> > > > Hi,
> > > >
> > > > I am trying to implement a custom Interceptor to have a global
> > > > custom "security" logger in my web app.
> > > >
> > > > The target is to log all the datas sended to the server during
> > > > update, save, delete etc... to have a custom logger for security
> > > reasons.
> > > >
> > > > In case of GET and POST (query string param or form data without
> > > > json object) :
> > > > HttpParameters httpParameters =
> > > ActionContext.getContext().getParameters();
> > > > works fine.
> > > >
> > > > But in case of json params in POST (request payload) the previous
> > > > code doesn't works
> > > > when the params is serialize via : JSON.stringify(...)
> > > >
> > > > code sample:
> > > > jQuery.ajax({
> > > >    type: 'POST',
> > > >    url: url,
> > > >    data: JSON.stringify(data),
> > > >    dataType: 'json',
> > > >    async: false ,
> > > >    contentType: 'application/json; charset=utf-8',
> > > >    success: function(){
> > > >        self.load();
> > > >    },
> > > >    error: function(data) {
> > > >        if (data.responseText) {
> > > >           var error = JSON.parse(data.responseText);
> > > >        }
> > > >    }
> > > >
> > > > My custom Interceptor is added at the end of my stack after the json
> > > > interceptor like this :
> > > >         <interceptor-ref name="json">
> > > >               <param name="contentType">application/json</param>
> > > >           </interceptor-ref>
> > > >           <interceptor-ref name="commonSecurityLogger"/>
> > > > </interceptor-stack>
> > > >
> > > >
> > > >
> ---------------------------------------------------------------------
> > > > To unsubscribe, e-mail: [hidden email]
> > > > For additional commands, e-mail: [hidden email]
> > > >
> > >
> > > This Email was scanned by Sophos Anti Virus
> > >
> > You are right I have tried to use "request.getReader()" and after
> > the json object was not available anymore.
> > How can I rewrite them ? Should I do the same like in JSONInterceptor ?
> >
>
>
> Well, when your interceptor reads the inputsream it has to preserve data
> in memory in some way and your actions must read it from there.
>
> You can try to copy the inputstream to a byte array first (by using
> ByteArrayOutputStream) and wrap request.getInputStream() with a
> ByteArrayInputStream pointing to same byte array. Of course that will
> cause issues if your users upload large amount of data.
>
>
> Regards,
> Christoph
>
> This Email was scanned by Sophos Anti Virus
>
So It is possible in my web app to post large amount of data...

I am trying to use the reflexion API to retrieve all getter of actions and then try to get one by one getters...

I don't think if it's a better solution to do that.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

Snowball RC


On 2017-03-23 14:28 (+0200), "Snowball RC"<[hidden email]> wrote:

>
>
> On 2017-03-23 14:23 (+0100), Christoph Nenning <[hidden email]> wrote:
> > > <[hidden email]> wrote:
> > > > Hi,
> > > >
> > > > AFAIK that is defined in servlet spec. Only parameters with
> > content-type "
> > > > application/x-www-form-urlencoded" are made available via
> > getParameters().
> > > > The struts method you mentioned just forwards to according method of
> > > > servlet api.
> > > >
> > > > Your json data can only be read by consuming request inputstream. If
> > you
> > > > do so in your interceptor it is not available anymore to your actions
> > (or
> > > > struts json interceptor) so you must rewrite them, too.
> > > >
> > > > Regards,
> > > > Christoph
> > > >
> > > >
> > > >
> > > > > From: "Snowball RC" <[hidden email]>
> > > > > To: <[hidden email]>,
> > > > > Date: 23.03.2017 11:28
> > > > > Subject: What is the best way to get all JSON params in custom
> > > > > Interceptor to log them all in a custom logger ?
> > > > >
> > > > > Hi,
> > > > >
> > > > > I am trying to implement a custom Interceptor to have a global
> > > > > custom "security" logger in my web app.
> > > > >
> > > > > The target is to log all the datas sended to the server during
> > > > > update, save, delete etc... to have a custom logger for security
> > > > reasons.
> > > > >
> > > > > In case of GET and POST (query string param or form data without
> > > > > json object) :
> > > > > HttpParameters httpParameters =
> > > > ActionContext.getContext().getParameters();
> > > > > works fine.
> > > > >
> > > > > But in case of json params in POST (request payload) the previous
> > > > > code doesn't works
> > > > > when the params is serialize via : JSON.stringify(...)
> > > > >
> > > > > code sample:
> > > > > jQuery.ajax({
> > > > >    type: 'POST',
> > > > >    url: url,
> > > > >    data: JSON.stringify(data),
> > > > >    dataType: 'json',
> > > > >    async: false ,
> > > > >    contentType: 'application/json; charset=utf-8',
> > > > >    success: function(){
> > > > >        self.load();
> > > > >    },
> > > > >    error: function(data) {
> > > > >        if (data.responseText) {
> > > > >           var error = JSON.parse(data.responseText);
> > > > >        }
> > > > >    }
> > > > >
> > > > > My custom Interceptor is added at the end of my stack after the json
> > > > > interceptor like this :
> > > > >         <interceptor-ref name="json">
> > > > >               <param name="contentType">application/json</param>
> > > > >           </interceptor-ref>
> > > > >           <interceptor-ref name="commonSecurityLogger"/>
> > > > > </interceptor-stack>
> > > > >
> > > > >
> > > > >
> > ---------------------------------------------------------------------
> > > > > To unsubscribe, e-mail: [hidden email]
> > > > > For additional commands, e-mail: [hidden email]
> > > > >
> > > >
> > > > This Email was scanned by Sophos Anti Virus
> > > >
> > > You are right I have tried to use "request.getReader()" and after
> > > the json object was not available anymore.
> > > How can I rewrite them ? Should I do the same like in JSONInterceptor ?
> > >
> >
> >
> > Well, when your interceptor reads the inputsream it has to preserve data
> > in memory in some way and your actions must read it from there.
> >
> > You can try to copy the inputstream to a byte array first (by using
> > ByteArrayOutputStream) and wrap request.getInputStream() with a
> > ByteArrayInputStream pointing to same byte array. Of course that will
> > cause issues if your users upload large amount of data.
> >
> >
> > Regards,
> > Christoph
> >
> > This Email was scanned by Sophos Anti Virus
> >
> So It is possible in my web app to post large amount of data...
>
> I am trying to use the reflexion API to retrieve all getter of actions and then try to get one by one getters...
>
> I don't think if it's a better solution to do that.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Any other possibility to do that in Struts2 ?

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: What is the best way to get all JSON params in custom Interceptor to log them all in a custom logger ?

Christoph Nenning
> > > > > Hi,
> > > > >
> > > > > AFAIK that is defined in servlet spec. Only parameters with
> > > content-type "
> > > > > application/x-www-form-urlencoded" are made available via
> > > getParameters().
> > > > > The struts method you mentioned just forwards to according
method of
> > > > > servlet api.
> > > > >
> > > > > Your json data can only be read by consuming request
inputstream. If
> > > you
> > > > > do so in your interceptor it is not available anymore to your
actions

> > > (or
> > > > > struts json interceptor) so you must rewrite them, too.
> > > > >
> > > > > Regards,
> > > > > Christoph
> > > > >
> > > > >
> > > > >
> > > > > > From: "Snowball RC" <[hidden email]>
> > > > > > To: <[hidden email]>,
> > > > > > Date: 23.03.2017 11:28
> > > > > > Subject: What is the best way to get all JSON params in custom

> > > > > > Interceptor to log them all in a custom logger ?
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > I am trying to implement a custom Interceptor to have a global

> > > > > > custom "security" logger in my web app.
> > > > > >
> > > > > > The target is to log all the datas sended to the server during

> > > > > > update, save, delete etc... to have a custom logger for
security
> > > > > reasons.
> > > > > >
> > > > > > In case of GET and POST (query string param or form data
without
> > > > > > json object) :
> > > > > > HttpParameters httpParameters =
> > > > > ActionContext.getContext().getParameters();
> > > > > > works fine.
> > > > > >
> > > > > > But in case of json params in POST (request payload) the
previous

> > > > > > code doesn't works
> > > > > > when the params is serialize via : JSON.stringify(...)
> > > > > >
> > > > > > code sample:
> > > > > > jQuery.ajax({
> > > > > >    type: 'POST',
> > > > > >    url: url,
> > > > > >    data: JSON.stringify(data),
> > > > > >    dataType: 'json',
> > > > > >    async: false ,
> > > > > >    contentType: 'application/json; charset=utf-8',
> > > > > >    success: function(){
> > > > > >        self.load();
> > > > > >    },
> > > > > >    error: function(data) {
> > > > > >        if (data.responseText) {
> > > > > >           var error = JSON.parse(data.responseText);
> > > > > >        }
> > > > > >    }
> > > > > >
> > > > > > My custom Interceptor is added at the end of my stack after
the json
> > > > > > interceptor like this :
> > > > > >         <interceptor-ref name="json">
> > > > > >               <param
name="contentType">application/json</param>
> > > > > >           </interceptor-ref>
> > > > > >           <interceptor-ref name="commonSecurityLogger"/>
> > > > > > </interceptor-stack>
> > > > > >
> > > > > >
> > > > > >
> > >
---------------------------------------------------------------------
> > > > > > To unsubscribe, e-mail: [hidden email]
> > > > > > For additional commands, e-mail: [hidden email]
> > > > > >
> > > > >
> > > > > This Email was scanned by Sophos Anti Virus
> > > > >
> > > > You are right I have tried to use "request.getReader()" and after
> > > > the json object was not available anymore.
> > > > How can I rewrite them ? Should I do the same like in
JSONInterceptor ?
> > > >
> > >
> > >
> > > Well, when your interceptor reads the inputsream it has to preserve
data
> > > in memory in some way and your actions must read it from there.
> > >
> > > You can try to copy the inputstream to a byte array first (by using
> > > ByteArrayOutputStream) and wrap request.getInputStream() with a
> > > ByteArrayInputStream pointing to same byte array. Of course that
will

> > > cause issues if your users upload large amount of data.
> > >
> > >
> > > Regards,
> > > Christoph
> > >
> > > This Email was scanned by Sophos Anti Virus
> > >
> > So It is possible in my web app to post large amount of data...
> >
> > I am trying to use the reflexion API to retrieve all getter of
> actions and then try to get one by one getters...
> >
> > I don't think if it's a better solution to do that.
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [hidden email]
> > For additional commands, e-mail: [hidden email]
> >
> >
> Any other possibility to do that in Struts2 ?
>


Well, doing it with reflection would mean to populate the action as ususal
and logging it's values afterwards. IMO that should work. An issue could
be that you don't log data which is present in JSON but not applied to
actions.


Logging data from request body is general a hard issue for web
applications, no matter what programming language or framework. A simple
way to avoid the memory issue of my previous proposal would be to store
data on disk (which introduces other issues of course).

Or if you use a reverse proxy like apache or nginx you could log data
there.

Another option could be to check if your application server provides an
option to log request data.


Regards,
Christoph

This Email was scanned by Sophos Anti Virus
Loading...