Search code examples
spring-mvcspring-restcontrollerspring-rest

How to create a Spring Interceptor for Spring RESTful web services


I have some Spring RESTful (RestControllers) web services with no web.xml and I am using Spring boot to start the services.

I want to add authorization layer for the web services and wanted to route all the http requests to one front controller before actually calling the web service itself. (I have a code to simulate sessions behavior at the autherisation layer, to validate a user based on a generated key that I send with each of the httpRequest from the client).

Is there any Standard Spring solution on routing all the requests to a filter /front controller?

Thanks in advance, Praneeth

Edit: Adding my code

Controller: `

@RestController
public class UserService {
    UserDAO userDAO = new UserDAO();

    @RequestMapping(value="/login", method = RequestMethod.POST)
    @LoginRequired
    public String login(@RequestParam(value="user_name") String userName, @RequestParam(value="password") String password, HttpServletRequest request){
        return userDAO.login(userName, password);
    }
}`

Interceptor:

`

public class AuthenticationInterceptor implements HandlerInterceptor  {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        System.out.println("In Interceptor");
        //return super.preHandle(request, response, handler);
        return true;
    }
    @Override
    public void postHandle( HttpServletRequest request, HttpServletResponse response,
            Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("---method executed---");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
            Object handler, Exception ex) throws Exception {
        System.out.println("---Request Completed---");
    }
}

`

Interface. `

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequired {
}

`


Solution

  • Following steps can be taken to implement the interceptor with Spring:

    • Implement an interceptor class extending HandlerInterceptorAdapter class. Following is how the code could look like:

      public class LoginInterceptor extends HandlerInterceptorAdapter {
      
          @Override
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception)
          throws Exception {
          // TODO Auto-generated method stub
      
          }
      
          @Override
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
          throws Exception {
          // TODO Auto-generated method stub
      
          }
      
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      
              HandlerMethod handlerMethod = (HandlerMethod) handler;
      
              String emailAddress = request.getParameter("emailaddress");
              String password = request.getParameter("password");
      
              if(StringUtils.isEmpty(emailAddress) || StringUtils.containsWhitespace(emailAddress) ||
              StringUtils.isEmpty(password) || StringUtils.containsWhitespace(password)) {
                  throw new Exception("Invalid User Id or Password. Please try again.");
              }
      
              return true;
          }
      
      
      }
      
    • Implement an AppConfig class or add the addInterceptors in one of the existing Configuration class. Note the path pattern specified with the LoginInterceptor instance

      @Configuration  
      public class AppConfig extends WebMvcConfigurerAdapter  {  
      
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
             registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/account/login");
          }
      } 
      
    • Implement the controller method such as following:

      @Controller
      @RequestMapping("/account/login")
      public class LoginController {
      
          @RequestMapping(method = RequestMethod.GET)
          public String login() {
              return "login";
          }
      }