Earliest point to encrypt json payload in spring mvc application - spring-boot

I have an spring boot application serving restful api's.
I'd like to make sure that certain fields are masked / encrypted at the earliest possible time so that they are not shown in clear text in the application log ... via logback.
Is there an entry point / filter / sprint aspect I can implement so a to achieve this ?

As cearly explained in Ali Dehghani's Answer in this post the best place to do what you want to, is in a Response filter. So you have to write a class that implements the Filter interface and you filter your response in the doFilter method.
#Component
public class YourResponseFilter implements Filter {
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
...
// do your work there
}
}
You may or may not use the annotate your filter with #Component, depending in the fact if you want to filter all your reponses or not.
If you need more help let me know.

Related

How to log HTTP exchanges (including the payloads) in spring-boot with spring-web

Is there any way to log complete HTTP exchanges (request + response including headers + payloads) in a spring-web REST service?
I have seen the CommonsRequestLoggingFilter, but that only logs the request. Is there a matching CommonsResponseLoggingFilter? Or a different solution?
In Jersey this functionality is provided by LoggingFeature, you just need to enable it.
For the HTTP server I use the default Tomcat. There's AccessLogValve, but that doesn't log the payload.
Ideally I would want something at spring-web level, similar to Jersey, so I don't have to worry about it if I switch from Tomcat to Jetty or Undertow.
I am not sure if spring have any build-in filter which help to log both request/response.
But you can write customize filter to do it.
#Component
public class CustomLoggingFilter extends GenericFilterBean {
#Override
public void doFilter(
final ServletRequest req,
final ServletResponse res,
final FilterChain chain)
throws IOException, ServletException {
CachedBodyHttpServletRequest reqWrap = new CachedBodyHttpServletRequest(
(HttpServletRequest) req);
ContentCachingResponseWrapper resWrap = new ContentCachingResponseWrapper(
(HttpServletResponse) res);
chain.doFilter(reqWrap, resWrap);
resWrap.copyBodyToResponse();
}
}
CachedBodyHttpServletRequest and ContentCachingResponseWrapper can help you to access headers/datas multiple time and do few logging without broken any datas.
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/ContentCachingRequestWrapper.html
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/ContentCachingResponseWrapper.html

Servlet filter applied twice

I have an spring boot application exposing rest endpoints, inside the project there is a library that applies a filter:
#Component
#Order(1)
public class MyFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {}
It works fine, but there is a weird behavior I found. whenever my library(the one with the filter) makes a remote call to another rest service(i do it to evaluate certain logic based on the response), when that service returns a response, before returning, the filter is applied again, and of course, I do not want this behavior.
I am 100% certain this is what causes the 2nd call to the filter because if I omit the rest call, the filter is applied only once.
why are you doing "internal rest requests" ? instead of calling directly the underlying service?
use a FilterRegistrationBean
#Bean
public FilterRegistrationBean<MyFilter> loggingFilter(){
FilterRegistrationBean<MyFilter> registrationBean
= new FilterRegistrationBean<>();
registrationBean.setFilter(new MyFilter());
registrationBean.addUrlPatterns("/users/*");
return registrationBean;
}

configuring interceptors to perform "pre-tasks" on hitting endpoints in spring based web app

I am required to perform some pre-task whenever few specific endpoints are hit in my spring based web app. I came across the interceptor component provided by the spring-security framework. I searched various forums but didn't find relevant answers for configuring and adding interceptor.
Consider a situation where I am required to set some key=value in a database by sending POST request in the database whenever the user hits following endpoints.
/endpoint1
/endpoint2
/endpoint3
/endpoint4
After completion of the pre-task user should be redirected to the origin endpoint.
How can this be achieved using an interceptor in the spring-security framework?
Spring Security is for security stuff related to Authentification and Authorization. You can trigger some action if somebody logged in, but if you just need to trigger action for each request than Spring Security is not a good place for that (according to business logic), better add just filter. Anyway answering to your question:
The best way is to add custom filter to Spring Security Filter Chain:
You have to overwrite:
#Configuration
public class CustomWebSecurityConfigurerAdapter
extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(
new CustomFilter(), BasicAuthenticationFilter.class);
}
}
and create your custom filter:
public class CustomFilter extends GenericFilterBean {
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//your logic here
chain.doFilter(request, response); //it's needed to pass your request father
}
}
Code taken from baeldung.com see for more information

How to create servlet filter to authorize the request?

How to create spring servlet filter to authorize the request.
Need to add a filter in the spring security filter chain that updates the user with few details (re-loading permissions or anything) for every request, if they need to be changed.
Need some sample code snippet to follow or understand.
Thanks in advance.
To add a custom filter you should extend the org.springframework.web.filter.GenericFilterBean, like so:
public class MySecurityFilter extends GenericFilterBean {
#Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
The next step is to actually register the filter by overriding the configure method of WebSecurityConfigurerAdapter:
#Configuration
public class CustomWebSecurityConfigurerAdapter
extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterAfter(
new MySecurityFilter(), BasicAuthenticationFilter.class);
}
}
As you can see the filter is added by adding the filter to the HttpSecurity object. The method that is used is the addFilterAfter which basically allocates your filter after the one that you provide in the second argument, in this example is the BasicAuthenticationFilter, so your filter will be executed after this one, in the spring secuirty chain of filters.
Update
Refer to this link to personalize the authorization of your servlet. The method gives you an Authentication object, through which you can obtain your User object and perform additional checks.

Spring Security Filter and Posted Data

I wrote a custom Spring Security filter that needs to user XML data that was posted to it. How would the filter get the posted data?
It's not a really Spring Security-specific problem, since you are likely just implementing the javax.servlet.Filter interface. In this case, you are implementing the method:
public void doFilter ( ServletRequest request, ServletResponse response,
FilterChain chain ) throws IOException, ServletException;
You can then cast the ServletRequest to a HttpServletRequest if you need HTTP-specific data (which is usually required):
import javax.servlet.http.HttpServletRequest;
// ...
HttpServletRequest httpRequest = (HttpServletRequest) request;
String xml = httpRequest.getParameter("xml");
If you are extending one of the standard Spring Security filters, make sure you look at the source for the filter you're extending! Many of them already override doFilter and expect that you will override another method to augment their behavior.
Read through the documentation for AbstractAuthenticationProcessingFilter (based on your earlier question, I guess this is the class that your custom filter extends), the abstract method to implement is attemptAuthentication, which receives HttpServletRequest and HttpServletResponse as parameters:
Parameters:
request - from which to extract parameters and perform the authentication
response - the response, which may be needed if the implementation has to do a redirect as part of a multi-stage authentication process (such as OpenID).

Resources