Невозможно использовать PermitAll() с Spring Boot 2.3.4, чтобы разрешить доступ к пользовательскому интерфейсу Swagger после интеграции с аутентификацией по ключу API

#spring-boot #spring-security #swagger #spring-security-rest

#пружинный ботинок #пружина-безопасность #развязность #весна-безопасность-отдых #spring-boot #spring-security #swagger #spring-security-rest

Вопрос:

Я попытался интегрировать механизм аутентификации по ключу API в приложение Spring Boot следующим образом:

  1. Создан a CustomAPIKeyAuthFilter , который расширяется AbstractPreAuthenticatedProcessingFilter там, где он получает предварительно аутентифицированного участника из заголовков запроса.
 public class CustomAPIKeyAuthFilter extends AbstractPreAuthenticatedProcessingFilter {

    private String principalRequestHeader;
    private String principalAuthKey;
    public CustomAPIKeyAuthFilter(String principalRequestHeader, String principalAuthKey) {
        this.principalRequestHeader = principalRequestHeader;
        this.principalAuthKey = principalAuthKey;
    }

    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        return request.getHeader(principalRequestHeader);
    }

    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
//      anything to be returned here??
        return "TBD";
    }
}
  
  1. Создан WebSecurityConfig , который расширяется WebSecurityConfigurerAdapter . В этом случае пользовательский фильтр вводится внутри переопределенного метода protected void configure(HttpSecurity httpSecurity) {}
 @EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${superuser}")
    private String principalRequestHeader;

    @Value("${superuserauthkey}")
    private String principalRequestValue;
    
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        CustomAPIKeyAuthFilter filter = new CustomAPIKeyAuthFilter(principalRequestHeader, principalRequestValue);
        filter.setAuthenticationManager(new AuthenticationManager()  {

            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                String principal = (String) authentication.getPrincipal();
                
                
                if (principalRequestValue.equals(principal)){
                    authentication.setAuthenticated(true);
                    
                } else {
                    throw new BadCredentialsException("Missing API Key");
                }
                
                return authentication;
            }
        });

        
        httpSecurity.
              cors().and().
              csrf().disable().authorizeRequests()
              .antMatchers("**swagger**").permitAll() // this is the part that is not working for me
              .anyRequest().authenticated()
              .and()
              .addFilter(filter)
              .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

  

Как вы можете видеть из приведенного выше комментария, несмотря на то, что я использовал permitAll , я получаю ошибку 401 No pre-authenticated principal found in request во время выполнения, если я пытаюсь получить доступ к пользовательскому интерфейсу Swagger, который работал до введения зависимостей, связанных с безопасностью spring-boot-starter, в моем pom.xml . Есть ли лучший способ исключить только пользовательский интерфейс swagger из списка конечных точек URL, которым требуется аутентификация на основе ключа API?

Примечание: я использую реализацию Swagger на springfox-swagger2, а используемая версия — 2.8.0.

Ответ №1:

У Swagger есть конечная точка api, которая должна быть разрешена на уровне безопасности, добавьте приведенный ниже фрагмент в WebSecurityConfig.class

 @Override
public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/v2/api-docs",
                "/configuration/ui",
                "/swagger-resources/**",
                "/configuration/security",
                "/swagger-ui.html",
                "/webjars/**");
}
  

Вы также можете попробовать permitAll() использовать включенные шаблоны.Это исключит проверку подлинности swagger.