When sould I use HandlerInterceptor and ClientHttpRequestInterceptor? - java

I need to create a http interceptor for my spring boot app to check if the request's authorization heathers are valid, so I searched and it seems that I can use HandlerInterceptor or ClientHttpRequestInterceptor to do it.
What would be the ideal interceptor in this case? I need all requests to check this and deny access if they don't pass but to me it looks like both of the interceptors do the same thing, so what is the difference between each one?
Important detail:
I'm using #RestController to create my routes and if the route has an specific annotation (something like #IgnoreAuthentication) the interceptor won't need to check the authentication.

Related

Spring execute a method in all the controllers methods without injecting the service

I have an external IAM service (provides authentication and authorization features) which I would like to use to authenticate user requests.
I will ignore the code in below examples as it is not relevant.
In my IAMServiceImpl I have the authenticate(String token) method, which will validate the token.
I would like to reuse this method in all the controller methods, but I would like to avoid injecting the IAMServiceImpl in all the controllers.
Question: How can I register this method to be called at the beginning of each controller method, without injecting the service in all the controllers.
NOTE I have to pass the token to the service, which I will get from request headers.
Thank you!
You should use Aspect Oriented Programming, it is good solution for your use case.
Have a look at Spring's documentation for AOP, specifically #Before advice.
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop
There are two ways (might be more):
1) Spring AOP: You can setup an advice to be executed before controller gets called in.
2) Filter chain (more suitable for your use-case): Spring security has a set of filters that can be used to provide authentication and authorization.
Maybe you could use Shiro or Spring Security to help you achieve these like filters, or you could use Aspect Oriented Programming before each Controller.

Automatical request decryption in Spring controller

For communication we will send encrypted messages between our app and backend. These messages contains encrypted payload which will be json. What is the best way to automatically decrypt the payload and pass it as unmarshalled object to the Spring rest controller. Should I utilize some Spring custom editors?
UPDATE
The problem is quite complicated as we need to use HSM and DB for decryption. I know I can handle this in filter, but I guess the approach is not really good one.
Replacing the request content seems odd to me not to mention the need for starting DB transaction.
Spring interceptors will not help as they are just alternative to filters. We thought about AOP or some Facade before each service call, which fill take care about the messege decryption and unmarshalling.
This seems like a job for spring filters. Filters can intercept your http requests. You can configure filter bean by adding component implementing javax.servlet.Filter interface.
#Component
public class EncodingFilter implements Filter {
}
You can read more on this matter based on example here and here.

spring http outbound gateway customization

My requirement is to call siebel soap webservice, In the process handle request and response on a same method call, so that I can add token to the request header from the apache common pool and once get the response with token, grab the token from response and send it to pool. Here I have mechanism to verify old token too,
I need request token and response token on same class.
Future planning to add retry mechanism.
Currently I am using SI Http outbound gateway.
Any thoughts, appreciate it.
Thanks
So, what you need is named pre- and post-process. Not sure why you don't use Spring Integration WS support for calling that Siegel service, but even with the HTTP you can get a gain via Interceptor abstraction.
What I mean that you can inject RestTemplate into HTTP Outbound Gateway supplied with the ClientHttpRequestInterceptor implementation to provide a desired logic.
If you'd use WS Outbound Gateway, you could do that in the similar ClientInterceptor abstraction.
Of course, you can achieve that via HeaderMapper implementation, but that has different responsibility...
I found the way to achieve this,
Created a class to extends HttpRequestExecutingMessageHandler than overrided handleRequestMessage()
http://docs.spring.io/spring-integration/reference/html/http.html#http-outbound

Filter, get url before controller (Spring MVC)

I want to write filter, and get client httprequest before controller and make some code, depends on URL.
Request can be: HttpRequest, MultipartHttpServletRequest, can be POST or GET. I need to make request to another REST API, if the URL of this request starts with api.
You should use Spring org.springframework.web.servlet.HandlerInterceptor
(hopefully this answer explain how to use it)
(or you could use an simple Servlet-Filter - see also this question Spring HandlerInterceptor vs Servlet Filters it discuss the difference between them)

Send redirect from a JAX-RS service

Is it possible to have a JAX-RS web service redirect to another web page?
Like as you would do with Servlet response.sendRedirect("http://test/test.html").
The JAX-RS web service should itself redirect. I'm using RESTEasy if that's relevant.
Yes, you can do this in Jersey or any JAX-RS implementation (including RestEasy) if your return type is a Response (or HttpServletResponse)
https://eclipse-ee4j.github.io/jersey.github.io/apidocs/1.19.1/jersey/javax/ws/rs/core/Response.html
You can use either of the following:
Response.temporaryRedirect(URI)
Response.seeOther(URI)
"Temporary Redirect" returns a 307 status code while "See Other" returns 303.
For those like me looking for 302 that fall on this answer.
By looking the code of
Response.temporaryRedirect(URI)
You can customize your response code like this :
Response.status(int).location(URI).build()
Note that status code are define in enum
Response.Status
And for example 302 is Response.Status.FOUND
Extending smcg# answer above,
You can achieve this by altering the request context in a ContainerRequestFilter by using ContainerRequestContext.setRequestUri(URI). If you see the JAX-RS specification (Section 6.2) here, there is a mention of #PreMatching request filters. According to the documentation;
A ContainerRequestFilter that is annotated with #PreMatching is executed upon
receiving a client request but before a resource method is matched. Thus, this type of filter has the ability
to modify the input to the matching algorithm (see Section 3.7.2) and, consequently, alter its outcome.
A very naive filter can be like this;
#PreMatching
class RedirectFilter: ContainerRequestFilter {
override fun filter(requestContext: ContainerRequestContext?) {
requestContext!!.setRequestUri(URI.create("<redirect_uri>"))
}
}

Categories

Resources