#java #spring #http #swagger
#java #spring #http #swagger
Вопрос:
У меня есть проект spring boot с некоторыми конечными точками rest и страницей пользовательского интерфейса swagger. Я могу успешно получить доступ к странице swagger по адресу http://localhost:8080/swagger-ui.html #/ с помощью springfox-swagger-ui и springfox-swagger2 2.9.2 (или в http://localhost:8080/swagger-ui / при использовании springfox-boot-starter 3.0.0). В рамках моей конфигурации безопасности у меня есть простой фильтр аутентификации, который можно использовать для проверки ключей api, которые пользователь сможет ввести на странице swagger.
Однако моя проблема в том, что каждый раз, когда я захожу на страницу swagger, она автоматически вызывает метод attemptAuthentication() в моем фильтре (и несколько раз). Этого не должно произойти. Он должен вызываться только тогда, когда я ввожу ключевую информацию, а затем нажимаю авторизовать на странице.
HttpServletRequest, пытающийся выполнить аутентификацию, имеет один и тот же тип для всех 10 запросов. Все запускаемые запросы поступают на разные URI. Это тип запроса
SecurityContextHolderAwareRequestWrapper[org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest]
И это все URI:
/swagger-ui/
/swagger-ui/springfox.css
/swagger-ui/swagger-ui.css
/swagger-ui/swagger-ui-bundle.js
/swagger-ui/swagger-ui-standalone-preset.js
/swagger-ui/springfox.js
/swagger-ресурсы / конфигурация / пользовательский интерфейс
/swagger-ресурсы / конфигурация / безопасность
/swagger-ресурсы
/v2/api-docs
SimpleAuthFilter
public class SimpleAuthFilter extends AbstractAuthenticationProcessingFilter {
public SimpleAuthFilter(final RequestMatcher req) {
super(req)
setAuthenticationManager(new MyAuthManager())
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) {
// -> Getting called here when visting swagger page
}
@Override
protected void successfulAuthentication(final HttpServletRequest req, final HttpServletResponse, final FilterChain chain, final Authentication auth) throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(auth);
chain.doFilter(req, res);
}
}
MyAuthManager
private class MyAuthManager implements AuthenticationManager {
@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
throw new AuthenticationServiceException("Bad auth");
}
}
MySecurityConfig
@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity sec) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(filter(), AnonymousAuthenticationFilter.class)
.authorizeRequests()
...
;
}
@Bean
public SimpleAuthFilter filter() {
RequestMatcher match = new OrRequestMatcher(new AntPathRequestMatcher("/**"));
return new SimpleAuthFilter(match);
}
}
SwaggerConfiguration
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("MyProject"))
.paths(PathSelectors.any())
.build()
.enableUrlTemplating(true)
.securitySchemes(Collections.singleton(new ApiKey("mykey", "Authorization", "header")))
.securityContexts(Collections.singleton(context()));
}
public SecurityContext context() {
return SecurityContext.builder()
.securityReferences(securityReferences())
.forPaths(PathSelectors.any())
.build();
}
public List<SecurityReference> securityReferences() {
return Collections.singletonList(new SecurityReference("mykey", new AuthorizationScope[]{new AuthorizationScope("global", "accessEverything")}));
}
}
Я думал, что проблема может быть связана с необходимостью настройки обработчиков ресурсов путем расширения WebMvcConfigurationSupport, но каждый раз, когда я пытался, на странице swagger возникали проблемы. Или мне может понадобиться как-то исключить эти пути URI с помощью нескольких antMatcher() ?
Я пробовал использовать разные зависимости swagger, перемещая местоположение фильтра в конфигурации HttpSecurity, обработчики ресурсов, контроллеры просмотра, но у меня ничего не получилось.
Я использую spring-boot-starter-web, spring-boot-starter-security 2.3.4 и spring-boot-starter-validation 2.4.0
Ответ №1:
Я выяснил частичный ответ, который заключается в том, что RequestMatcher, используемый для создания фильтра в MySecurityConfig, вместо этого должен быть специфичным ТОЛЬКО для конечных точек, а не быть /**
, что приведет к тому, что фильтр фактически попытается выполнить аутентификацию даже при посещении страницы swagger.
Проблема с использованием AntPathRequestMatcher заключается в том, что мои конечные точки не имеют шаблона с префиксом, например,
/endpoint1
/endpoint2