Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot - Pass argument from interceptor to method in controller

For learning purposes, I have made a custom authentication system where I pass a token from the client to the server through the Authorization header.

In the server side, I'd like to know if it's possible to create in the interceptor, before the request reaches a method in the controller, an User object with the email from the token as a property, and then pass this user object to every request where I require it.

This what I'd like to get, as an example:

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index(final User user) {
        return user.getEmail();
    }

}

public class User {
    private String email;
}

Where user is an object that I created in the pre-interceptor using the request Authorization header and then I can pass, or not, to any method in the RestController.

Is this possible?

like image 579
Ulises CT Avatar asked Nov 19 '19 20:11

Ulises CT


1 Answers

Recommended solution

I would create a @Bean with @Scope request which would hold the user and then put the appropriate entity into that holder and then take from that holder inside the method.

@Component
@Scope("request")
public class CurrentUser {
    private User currentUser;

    public User getCurrentUser() {
        return currentUser;
    }

    public void setCurrentUser(User currentUser) {
        this.currentUser = currentUser;
    }
}

and then

@Component
public class MyInterceptor implements HandlerInterceptor {

   private CurrentUser currentUser;

   @Autowired
   MyInterceptor(CurrentUser currentUser) {
       this.currentUser = currentUser;
   }

   @Override
   public boolean preHandle(
      HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      this.currentUser.setCurrentUser(new User("whatever"));
      return true;
   }
}

and in the Controller

@RestController
public class HelloController {

    private CurrentUser currentUser;

    @Autowired
    HelloController(CurrentUser currentUser) {
        this.currentUser = currentUser;
    }

    @RequestMapping("/")
    public String index() {
        return currentUser.getCurrentUser().getEmail();
    }

}

Alternative solution

In case your object that you would like to have, only contains one field, you can just cheat on that and add that field to the HttpServletRequest parameters and just see the magic happen.

@Component
public class MyInterceptor implements HandlerInterceptor {
   @Override
   public boolean preHandle(
      HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      //TRY ONE AT THE TIME: email OR user
      //BOTH SHOULD WORK BUT SEPARATELY OF COURSE
      request.setAttribute("email", "[email protected]");
      request.setAttribute("user", new User("[email protected]"));
      return true;
   }
}
like image 111
xenteros Avatar answered Sep 24 '22 16:09

xenteros