Используйте AbstractAuthenticationProcessingFilter для нескольких URL-адресов

У меня есть следующие шаблоны конечных точек в моем приложении

  1. /токен -- доступен всем
  2. /rest/securedone/** -- требует аутентификации
  3. /rest/securedtwo/** -- требует аутентификации
  4. /rest/unsecured/** -- не требует аутентификации

На данный момент я могу получить доступ к конечной точке /token. Но /rest/securedone/** и /rest/unsecured/** возвращают 401, когда токен (JWT) не отправляется. Я намерен защитить /rest/securedone/**, и это нормально, /rest/unsecured/** должен быть доступен.

Моя конфигурация httpSecurity выглядит следующим образом:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .cors()
            .and()
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/token").permitAll()
                .antMatchers("/rest/secured/**").authenticated()
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
            .and()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);

    http.headers().cacheControl();
}

и мой расширенный класс AbstractAuthenticationProcessingFilter выглядит следующим образом:

public class MyAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {

private static Logger log = LoggerFactory.getLogger(MyAuthenticationTokenFilter.class);

public MyAuthenticationTokenFilter() { super("/rest/**");  }

@Override
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, ServletException {
    //authentication handling code
}


@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    super.successfulAuthentication(request, response, chain, authResult);
    chain.doFilter(request, response);
}
}

Может кто-нибудь, пожалуйста, помогите мне понять следующее:

  1. Когда используется MyAuthenticationTokenFilter? Для какого URL он будет вызываться? Почему /rest/unsecured/** также ожидает аутентификацию? Это происходит, даже если я прямо говорю .antMatchers("/rest/secured/**").permitAll(). я

  2. Могу ли я указать несколько шаблонов URL-адресов в вызове super(defaultFilterProcessingUrl) внутри конструктора MyAuthenticationTokenFilter? Например, если у меня есть другой URL-адрес, такой как /api/secured/, как я могу вызвать MyAuthenticationTokenFilter для запросов /api/secured/? Мне не нужна другая обработка аутентификации, поэтому я хочу повторно использовать этот фильтр.


person worldbeater    schedule 23.10.2017    source источник


Ответы (1)


Когда используется MyAuthenticationTokenFilter?

Этот фильтр используется для обработки запроса с учетными данными клиента, он будет фильтровать URL-адрес, когда RequestMatcher соответствует URL-адресу запроса, например, в вашей конфигурации он будет обрабатывать URL-адрес, соответствующий /rest/**, и попытается преобразовать учетные данные клиента в Authentication. (например, userInfo, role...), может возникнуть исключение при запросе с неправильными учетными данными клиента. Это отличается от authorizeRequests(xxx.authenticated() или xxx.permit()), authorizeRequests просто проверьте, есть ли у аутентификации какие-то специальные атрибуты (например, роль, область действия).

По аналогии, AbstractAuthenticationProcessingFilter просто кладет несколько карт (Authentication) в коробку (SecurityContext) разными клиентами, authorizeRequests просто отметьте, что в коробке есть нужная карта, иначе запрос будет отклонен. AbstractAuthenticationProcessingFilter все равно, кто/как использует карты, и authorizeRequests все равно, откуда берутся карты.

Могу ли я указать несколько шаблонов URL-адресов в вызове super(defaultFilterProcessingUrl) внутри конструктора MyAuthenticationTokenFilter?

Да, вы можете установить requiresAuthenticationRequestMatcher на setRequiresAuthenticationRequestMatcher, это заменит старое requiresAuthenticationRequestMatcher, например,

authenticationTokenFilter
    .setRequiresAuthenticationRequestMatcher(new OrRequestMatcher(                                                                                     
        new AntPathRequestMatcher("/rest/secured/**")                                                                                   
        , new AntPathRequestMatcher("/api/secured/**")                                                                            
     ));
person chaoluo    schedule 24.10.2017
comment
Большое спасибо за упрощенное объяснение и ваше время. Думаю, теперь у меня более четкое представление об этом. - person worldbeater; 24.10.2017