How to create a Spring Interceptor for Spring RESTful web services

后端 未结 5 1616
醉话见心
醉话见心 2020-12-01 12:31

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 th

相关标签:
5条回答
  • 2020-12-01 12:54

    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>
    
    0 讨论(0)
  • 2020-12-01 12:59

    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());
    
        }
    }
    
    0 讨论(0)
  • 2020-12-01 13:00

    After Spring 5 : Implementation should be like this: We should have a class that implements

    HandlerInterceptor 
    
        public class CustomInterceptor implements HandlerInterceptorr{
    }
    

    Then we can register this interceptor by a class that implements WebMvcConfigurer and override the method addInterceptors

    public class ServiceInterceptorAppConfig implements WebMvcConfigurer {
      @Autowired
      CustomInterceptor customInterceptor;
    
      @Override
      public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor);
      }
    }
    
    0 讨论(0)
  • 2020-12-01 13:05

    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.

    0 讨论(0)
  • 2020-12-01 13:17

    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";
          }
      }
      
    0 讨论(0)
提交回复
热议问题