Interceptor not working in Spring Boot GraphQL - java

Im using graphql-java-kickstart/graphql-spring-boot and I'd like to create an interceptor to add an HTTP header after processing the request.
When I'm sending a graphql request to the backend the the interceptor is not triggered. But some calls trigger the interceptor. For example when I'm opening /graphiql in my browser I see that the interceptor is triggered but when I send a graphql request from graphiql client it is not. Any idea why? Anybody got experience with this?
My config looks like this:
#Configuration
public class InterceptorConfig implements WebMvcConfigurer {
#Autowired
private TestInterceptor testInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(testInterceptor).addPathPatterns("/**");
}
}
Also my Interceptor:
#Slf4j
#Component
public class TestInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
// post processing
log.info("hello there");
}
}

I have following interceptor that successfully works in my project:
My WebConfig:
#Configuration
public class WebConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor);
}
#Autowired
private ControllerExecInterceptor requestInterceptor;
}
Where ControllerExecInterceptor defined as:
#Component
public class ControllerExecInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws AccessDeniedException, Exception {
// ...
}
#Override
public boolean postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws {
// ...
}
}

Related

How to trigger a callback post fetching an entity in spring boot

#Service
#GetMapping
public Foo findByFooId(#RequestParam(name = "fid") String fooId) {
return fooService.findByFooId(fooId);
}
I would like to trigger and save who viewed Foo, using a different method in FooService.
Its like a PostConstruct callback for a successful response of findByFooId. How can this be achieved
One way is going to a custom HandlerInterceptor implementation.
Definition of the interceptor
public class FooViewerInterceptor extends HandlerInterceptorAdapter {
#Autowired
FooService fooService;
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
// if response succeeded ? http response code = 200 ?
// extract the "who" logic
// extract the fooId from request path
fooService.viewedBy(fooId, userId); // example...
}
}
Register the interceptor. Note the path pattern specified with the custom interceptor instance.. just an example.
#Configuration
public class AppConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new FooViewerInterceptor()).addPathPatterns("/foo/**");
}
}

Interceptor not getting invoke

Based on some business logic i need to add query parameters to the request before it reaches the controller. In order to achieve this i have use the HandlerInterceptorAdapter to intercept the request.
I have a common lib where I have defined an interceptor and the dependent project has the controllers.
The interceptor is getting registered but when i invoke any api call it does not get invoked.
Interceptor in common lib
#Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler)
throws ServletException, IOException {
request.setAttribute("id", "123"); // this would be populated based on logic
return true;
}
}
Dependency
#Configuration
public class Resolver implements WebMvcConfigurer {
#Autowired
RequestInterceptor interceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor);
}
}
You don't have to annotate the RequestInterceptor. Please remove the #Component annotation from RequestInterceptor and #Autowired annotation from Resolver class to this dependency.
Instead of injecting, please instantiate it via default constructor.
public class RequestInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler)
throws ServletException, IOException {
request.setAttribute("id", "123"); // this would be populated based on logic
return true;
}
}
#Configuration
#EnableWebMvc
public class Resolver implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestInterceptor());
}
}

Using two interceptors in order

I am using Spring data rest and directly hitting the end point without a controller. As I wanted to validate the authorization, created an interceptor which validates the request based on some claims in the auth token.
#Configuration
#Order(1)
public class AuthConfig implements WebMvcConfigurer {
#Autowired
AuthInterceptor requestInterceptor;
#Bean
public MappedInterceptor exampleInterceptor() {
return new MappedInterceptor(new String[]{"/api/**"}, requestInterceptor);
}
}
#Component
public class AuthInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//validate authorization
if (authorized) {
return true;
} else {
return false;
}
}
}
this has been working great. Now I want to add other interceptor so that I can intercept one request and do some process. I am doing because this api doesn't have controller/service so intercepting it is what I thought way to do this
#Configuration
#Order(2)
public class ProcessConfiguration implements WebMvcConfigurer {
#Autowired
ProcessInterceptor requestInterceptor;
#Bean
public MappedInterceptor processInterceptor() {
return new MappedInterceptor(new String[]{"/api/entity/*"}, requestInterceptor);
}
}
#Component
public class ProcessInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// do some process
return true;
}
}
So I wanted to invoke auth interceptor first and process interceptor next if request is authorized. And I used #Order to reflect same but it is not working as expected. Is there any other way to do this or am I doing this wrong?

postHandle method is not invoking after http request handling

I've created following component to add X-Frame-Options into each response:
#Component
public class SecurityInterceptor extends HandlerInterceptorAdapter {
#PostConstruct
public void init(){
System.out.println("init");
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
response.addHeader("X-Frame-Options", "DENY");
}
}
method init executes on startup thus spring knows about this.
Also I have following rest service:
#PostMapping("/rest_upload")
public DeferredResult<ResponseEntity> upload(#RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) throws IOException {
final DeferredResult<ResponseEntity> deferredResult = new DeferredResult<>();
...
return deferredResult;
}
Unfortunately postHandle method is not invoking.
How can I correct it?
Spring knows about your Interceptor as just a bean and nothing more. You need to register it with InterceptorRegistry so that it is called as part of interceptors.
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Autowired
SecurityInterceptor securityInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(securityInterceptor);
}
}
You need a configuration class that extends WebMvcConfigurerAdapter and overrides the addInterceptor method:
#Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new SecurityInterceptor());
}
You also need to make sure you have enabled WebMvc in Spring.

Spring MVC Interceptor pattern

I have an interceptor that is supposed to intercept urls with different patterns like:
myapp/something/add/whatever
myapp/something/add
myapp/something/addWhatever
myapp/something/somethingelse/add
etc...
I have to intercept all urls which contain "add". There are a lot of somethings and somethingelses...
I have tried different patterns but it seems that they are all wrong:
**/add/*
**/add*
**/add/ ** (I added a blank space before the last ** so it doesn't format it to bold)
The interceptor is something like
public class MyInterceptor implements HandlerInterceptor {
}
I configure it in
#Configuration
#EnableSpringDataWebSupport
#EnableWebMvc
class MvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(getMyInterceptor()).addPathPatterns("**/add/*", "**/add/**", "**/add*");
}
#Bean
public MyInterceptor getMyInterceptor() {
return new MyInterceptor();
}
}
If I try to access
http://localhost:8080/myapp/something/add/somethingelse
my interceptor doesn't intercept it...
I had a similar issue. Here are my suggestions.
First use global interceptor and check the request uri:
public class MyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
if(uri.contains("/add")){
// do your job
}
return super.preHandle(request, response, handler);
}
}
In my case, alls add- methods are PUT, or POST requests. So I'm checking this in my global interceptor:
public class MyInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String method = request.getMethod();
if("PUT".equals(method) || "POST".equals(method)){
// do your job
}
return super.preHandle(request, response, handler);
}
}
configure it without addPathPatterns:
#Configuration
#EnableSpringDataWebSupport
#EnableWebMvc
class MvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(getMyInterceptor());
}
#Bean
public MyInterceptor getMyInterceptor() {
return new MyInterceptor();
}
}
Apparently this can be fixed by Change the bean type to "Mapped Interceptor" and wrapping it; though people don't seem to know why its an issue in the first place.
Based on this solution: https://stackoverflow.com/a/35948730/857994

Categories

Resources