#spring-boot #spring-security #swagger #spring-security-rest
#пружинный ботинок #пружина-безопасность #развязность #весна-безопасность-отдых #spring-boot #spring-security #swagger #spring-security-rest
Вопрос:
Я попытался интегрировать механизм аутентификации по ключу API в приложение Spring Boot следующим образом:
- Создан 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";
}
}
- Создан
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.