How to create a Spring Interceptor for Spring RESTful web services

倾然丶 夕夏残阳落幕 提交于 2019-11-27 22:55:25

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";
        }
    }
    

here an example of Interceptor :

public class AuthenticationInterceptor implements HandlerInterceptor  {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
         HandlerMethod handlerMethod = (HandlerMethod) handler;
        LoginRequired loginRequired = handlerMethod.getMethod().getAnnotation(LoginRequired.class);
        if (loginRequired == null) {
            return true;
        }

        String token = httpServletRequest.getParameter("token");

        if (StringUtils.isBlank(token)) {
            throw new MissingParameterException();
        }

        authenticationService.checkToken(token);

        return super.preHandle(httpServletRequest, httpServletResponse, handler);
    }
    @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---");
    }

We can create an annotation :

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

And then on controller, we had this annotation :

@RequestMapping(value = "/protected/controller")
@LoginRequired
public ResponseEntity<BaseResponse> controller() {
   ...
}

This is just a template/example to give you an idea. I hope this will help you.

There is a default solution for such things. spring security. And you will just have to implement something like:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .formLogin()
                .loginPage("/login")
                .failureUrl("/login?error")
                .usernameParameter("email")
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/")
                .permitAll();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }
}

the dependency for it is:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

You should add this to regsiter your interceptor

@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    AuthenticationInterceptor getAuthenticationInterceptor() {
        return new AuthenticationInterceptor();
    }

    @Override
    public void addInterceptors (InterceptorRegistry registry) {
        registry.addInterceptor(getAuthenticationInterceptor());

    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!