Secure spring webapp with cookies - spring

I am writing a little service which uses websockets (not topic!). I researched on how to secure websockets. But the documentations all say I have to secure the webapp like every other webapp (i.e. basic auth). I already tried basic auth and it seems to work. But I am in the need of securing the websocket service by cookies. So my question is:
How do you secure a spring webapp by cookies?
Regards

It can be done via servlet filters.
#Service
public class MyCookieAuthenticationFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//set principal to request after request was validated...
}
}
You have to register the filter too.

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

How to send custom request or response headers to APM from Keycloak Integration Spring Boot

I'm working on springboot project and we are using openId keycloak for authentication. I'm delaing with Multitenancy concept too. I want to sent custom header as request or either response and the same should be captured in APM as metadata. My current approach is as follows:
public class PreAuthFilter extends KeycloakPreAuthActionsFilter {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
((HttpServletResponse) response).addHeader("X-Realm",realm);
super.doFilter(request, response, chain);
}
But with above code i'm getting multiple response metatdata in APM
http.response.headers.X-Realm.0
http.response.headers.X-Realm.1
http.response.headers.X-Realm.2
http.response.headers.X-Realm.3
My expectation was single realm in APM Metadata
http.response.headers.X-Realm = "value"
I think SimpleHttpFacade is getting intialized during resolving deployment multiple times hence adding the response.
Need Suggestion
Thanx.
It appears this could be that the issue is more likely related to your application context spring and filters.
Since it's spring could you try OncePerRequestFilter ?
import org.springframework.web.filter.OncePerRequestFilter;
#Named
public class ApmFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// do apm things
filterChain.doFilter(request, response);
}
#Override
public void destroy() {
}
}

Earliest point to encrypt json payload in spring mvc application

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.

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

Spring security shares context between multiple threads, how can I avoid this?

I have been working on a spring-based service, using JWT for authentication.
The service handling the user requests calls an authorization service in a filter which sets up the security context and looks pretty much like this :
#Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {
private final Logger log = LoggerFactory.getLogger(this.getClass());
#Autowired
private AuthorizationServiceClient authorizationServiceClient;
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
User user = authorizationServiceClient.requestUserFromToken(request.getHeader("X-Auth-Token"));
SecurityContextHolder.getContext().setAuthentication(new UserAuthentication(user));
filterChain.doFilter(request, response);
SecurityContextHolder.getContext().setAuthentication(null);
} catch (HttpClientErrorException e) {
response.sendError(e.getStatusCode().value());
}
}
}
The AuthorizationServiceClient calls a remote service which handles the validation of the user's role and credentials.
I have been facing a very strange behavior :
When a page on my UI was making multiple request simultaneously, I end up getting a 500, caused by a NullPointerException.
The root cause is the Principal (containing the identity of the user) being null, when it shouldn't have.
After a painful investigation, I ended figuring that the SecurityContextHolder, even though it was using a ThreadLocal, was using sessions, and then would be shared between the threads.
The SecurityContextHolder.getContext().setAuthentication(null); was erasing the value used in concurrent threads when some requests were made in the same session, and was leading to the NPE.
So, if like me, you'd like to prevent the use of the sessions, you need to set up the security using :
http.
[...]
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).
[...]

Resources