antMatcher, похоже, не соответствует запрошенному пути (Spring Security)

#spring #spring-security

#весна #spring-security

Вопрос:

Мы пытаемся использовать Spring Security для защиты нашего веб-сервиса. Мы используем фильтр клиента (класс, который расширяется GenericFilterBean ) для чтения веб-токена JSON из заголовка HTTP. Если токен существует, он сохраняется как PreAuthenticatedAuthenticationToken в контексте безопасности. Защищенные ресурсы должны использовать нашего поставщика аутентификации клиента, чтобы проверить, действителен ли токен, и загрузить информацию о пользователе (которая включает роли).

Проблема в том, что я не могу настроить antMatcher для определенного ресурса. Если я использую antMatchers("/**").hasRole("USER") , ресурс защищен, но мы не хотим, чтобы все ресурсы совпадали, поэтому я попробовал AntMachter для одного ресурса, подобного этому:

 .antMatchers(HttpMethod.GET,"/rest/security/v1/currentuser").hasRole("USER")
  

Но этот сопоставитель, похоже, не соответствует запрошенному ресурсу, и поэтому поставщик аутентификации не вызывается. Но я не знаю почему. Я попробовал несколько комбинаций шаблона ant, но пока ничего не сработало.

Я установил точку останова в пользовательском фильтре для проверки текущего пути, и когда я вызываю servletRequest.getPathInfo() , я получаю именно то, что, по моему мнению, должно быть нашим шаблоном ant: /rest/security/v1/currentuser

Конфигурация Spring Security:

 @Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .anonymous().disable()
        .csrf().disable()
        .authorizeRequests()
            //.antMatchers("/**").hasRole("USER")
            .antMatchers(HttpMethod.GET, "/rest/security/v1/currentuser").hasRole("USER")
            .and()
        .httpBasic()
        .authenticationEntryPoint(authenticationEntryPoint())
            .and()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http
        .addFilterBefore(new JwtAuthenticationFilter(), BasicAuthenticationFilter.class);
}
  

Пользовательский фильтр:

 @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
    Optional<String> token = Optional.ofNullable(httpRequest.getHeader(HTTP_AUTHENTICATION_HEADER));
    if (token.isPresent()) {
        PreAuthenticatedAuthenticationToken requestAuthentication = new PreAuthenticatedAuthenticationToken(token, null);
        SecurityContextHolder.getContext().setAuthentication(requestAuthentication);
    }
    filterChain.doFilter(servletRequest, servletResponse);
}
  

Поставщик аутентификации:

 @Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {

    UsernamePasswordAuthenticationToken authenticationToken = null;

    try {

     // Token Validation, Loading User Info

    } catch (Exception e) {
        LOG.error("Failed to authenticate", e);
    }

    return authenticationToken;
}
  

Комментарии:

1. Проверка работоспособности: вы уверены, что запрос является правильным запросом GET? Ваша текущая конфигурация защищает только их, любой другой тип запроса к указанному пути может поступать прямо.

2. да, это запрос GET (до того, как я попробовал без метода HTTP, но он также не сработал)

3. Хм, интересно, связано ли это с шаблоном или с чем-то еще. Чтобы несколько доказать это, что, если вы используете matcher /rest / security /v1 /** для защиты всего в / v1 и не указываете конкретный метод HTTP? Я ожидаю, что это также ничего не защитит, хотя это определенно должно быть.

4. По какому URL-адресу развернуто ваше приложение? Сопоставитель ant должен содержать путь БЕЗ части приложения URL.

5. Ваш фильтр не вызывает вашего поставщика аутентификации, что может быть частью проблемы. Обычно фильтр, устанавливающий аутентификацию, вызывает диспетчер аутентификации, который затем вызывает зарегистрированных поставщиков аутентификации. Смотрите github.com/spring-projects/spring-security/blob/master/oauth2 / … для примера фильтра с аналогичной вашей ролью (которую вы, кстати, могли бы рассмотреть возможность использования вместо вашего пользовательского фильтра).