Метод AuthenticationManager.authenticate не вызывается

Я пытаюсь следовать коду аутентификации ключа API из этого ответа: https://stackoverflow.com/a/48448901

Я создал свой класс фильтра:

package com.propfinancing.CADData.web;

import javax.servlet.http.HttpServletRequest;
import org.slf4j.LoggerFactory;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

public class PullAPIKeyFromHeaderFilter extends AbstractPreAuthenticatedProcessingFilter {
  private String apiKeyHeaderName;
  
  public PullAPIKeyFromHeaderFilter(String apiKeyHeaderName) {
    this.apiKeyHeaderName = apiKeyHeaderName;
  }
  
  @Override
  protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
    String headerValue = request.getHeader(apiKeyHeaderName);
    return request.getHeader(headerValue);
  }

  @Override
  protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
    return apiKeyHeaderName;
  }
}

И затем я реализовал свою конфигурацию безопасности:

package com.propfinancing.CADData.web;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

@Configuration
@EnableWebSecurity
@Order(1)
public class APIKeySecurityConfig extends WebSecurityConfigurerAdapter {
  @Value("${caddata.apiKey.header.name}")
  private String apiKeyHeaderName;

  @Value("${caddata.apiKey}")
  private String apiKey;

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {
    PullAPIKeyFromHeaderFilter pullAPIKeyFromHeaderfilter = new PullAPIKeyFromHeaderFilter(apiKeyHeaderName);
    
    AuthenticationManager authManager = new AuthenticationManager() {
      @Override
      public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {
        String principal = (String) authentication.getPrincipal();
        if (!apiKey.equals(principal))
          throw new BadCredentialsException("Invalid API key");
        authentication.setAuthenticated(true);
        return authentication;
      }
    };
    pullAPIKeyFromHeaderfilter.setAuthenticationManager(authManager);
    
    httpSecurity.antMatcher("/**");
    httpSecurity.addFilter(pullAPIKeyFromHeaderfilter);
    httpSecurity.requiresChannel().anyRequest().requiresSecure();
    httpSecurity.csrf().disable();
    httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry urlAuthConfigurer = httpSecurity.authorizeRequests();
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.AuthorizedUrl authorizedUrl = urlAuthConfigurer.anyRequest();
    authorizedUrl.authenticated();
  }
}

Когда я делаю внешний вызов приложению с заголовком как часть запроса, я получаю ответ 403 Forbidden. Я вижу, как фильтр вытаскивает ключ из шапки. Эта часть работает.

Но метод authentication() не вызывается для проверки правильности заголовка. Я не уверен, что я пропустил, код выглядит так же для меня.

Любые идеи?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
0
30
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, неправильный базовый класс для https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.html :

The purpose is then only to extract the necessary information on the principal from the incoming request, rather than to authenticate them.

Вместо этого попробуйте расширить https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html.

Я попытаюсь перенести свой код в этот класс, но в примере, который я использую по ссылке, специально используется org.springframework.security.web.authentication.preauth.Abst‌​ractPreAuthenticated‌​ProcessingFilter

Neil 18.03.2022 03:25
Ответ принят как подходящий

Мне не удалось заставить работать приведенный выше код, но я изменил его, чтобы использовать второй ответ в теме (использование фильтра) https://stackoverflow.com/a/63852212 Он работает, как и ожидалось.

Другие вопросы по теме