web-dev-qa-db-fra.com

Comment créer un Spring Interceptor pour les services Web Spring RESTful

J'ai des services Web Spring RESTful (RestControllers) sans web.xml et j'utilise Spring Boot pour démarrer les services.

Je veux ajouter une couche d'autorisation pour les services Web et je voulais acheminer toutes les demandes http vers un contrôleur frontal avant d'appeler réellement le service Web lui-même. (J'ai un code pour simuler le comportement des sessions au niveau de la couche d'authentification, pour valider un utilisateur sur la base d'une clé générée que j'envoie avec chacune des httpRequest du client).

Existe-t-il une solution Standard Spring pour acheminer toutes les demandes vers un filtre/contrôleur frontal?

Merci d'avance, Praneeth

Modifier: ajouter mon code

Contrôleur: `

@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);
    }
}`

Intercepteur:

"

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 {
}

"

14
Praneeth Reddy

Les étapes suivantes peuvent être prises pour implémenter l'intercepteur avec Spring:

  • Implémentez une classe d'intercepteur étendant la classe HandlerInterceptorAdapter. Voici à quoi pourrait ressembler le code:

    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;
        }
    
    
    }
    
  • Implémentez une classe AppConfig ou ajoutez les addInterceptors dans l'une des classes de configuration existantes. Notez le modèle de chemin spécifié avec l'instance LoginInterceptor

    @Configuration  
    public class AppConfig extends WebMvcConfigurerAdapter  {  
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
           registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/account/login");
        }
    } 
    
  • Implémentez la méthode du contrôleur, comme suit:

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

voici un exemple d'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---");
    }

Nous pouvons créer une annotation:

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

Et puis sur le contrôleur, nous avons eu cette annotation:

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

Ceci est juste un modèle/exemple pour vous donner une idée. J'espère que cela t'aidera.

7
Pracede

Il existe une solution par défaut pour de telles choses. sécurité de printemps. Et vous aurez juste à implémenter quelque chose comme:

@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());
    }
}

la dépendance pour cela est:

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

Vous devez l'ajouter pour enregistrer votre intercepteur

@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {

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

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

    }
}
1
Edgar Orozco