Старый общий метод Tomcat
У меня есть собственный клапан аутентификации SAML 2.0, который я использую в настоящее время на некоторых автономных веб-серверах Tomcat для реализации единого входа.
Чтобы реализовать это, мы добавляем клапан в context.xml сервера tomcat, например (некоторые значения используются вместо реальных значений):
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<Valve className="example.CustomIdpValve"
idp="default" issuerName="SAMLIssuer"
idpUrl="https://example.idp.com/sso/"
certificatePath="${catalina.base}/conf/idp.cer"
/>
</Context>
Затем мы будем контролировать, какие конечные точки должны быть защищены на основе файла web.xml.
Новый метод Spring Boot Embedded Tomcat
Теперь мы используем этот клапан в автономных приложениях с пружинной загрузкой, работающих через встроенный tomcat с пружинной загрузкой. Мы добавляем один и тот же пользовательский клапан аутентификации в эти приложения через конфигурацию Java:
@Bean
public ConfigurableServletWebServerFactory embeddedServletContainerCustomizer() {
final CustomIdpValve customIdpValve = new CustomIdpValve();
final Valve singleSignOnValve = new SingleSignOn();
final TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addContextValves(customIdpValve);
factory.addContextValves(singleSignOnValve);
return factory;
}
Затем мы требуем, чтобы определенные роли были включены в UserPrincipal для доступа к приложению. Это снова настраивается с помощью конфигурации Java (роли извлекаются из application.properties):
@Component
public class WebAppInitializer implements ServletContextInitializer {
private final String[] roles;
public WebAppInitializer(@Value("${tomcat.embedded.roles}") final String[] roles) {
this.roles = roles;
}
public void onStartup(final ServletContext container) {
final ServletRegistration.Dynamic servlet = (ServletRegistration.Dynamic) container.getServletRegistration("default");
servlet.setServletSecurity(new ServletSecurityElement(new HttpConstraintElement(ServletSecurity.TransportGuarantee.NONE, roles)));
servlet.setServletSecurity(new ServletSecurityElement(new HttpConstraintElement(ServletSecurity.TransportGuarantee.CONFIDENTIAL, roles)));
}
}
Проблема
Это прекрасно работает — новые приложения весенней загрузки будут перенаправлять любой входящий запрос к IdP для аутентификации, который затем отправляет ответ SAML обратно на первоначально запрошенный URL-адрес, и страница загружается, как и ожидалось.
Проблема в том, что мы включили конечные точки привода Spring Boot, которым необходимо обойти эту аутентификацию. В частности, нам нужно, чтобы конечная точка проверки работоспособности /actuator/health
была незащищенной, чтобы ее можно было использовать в качестве проверки готовности для kubernetes.
Я не могу определить способ применения этого ServletSecurity
для каждого пути запроса, чтобы нам не требовалась аутентификация для любых запросов к пути /actuator/*
.
Возможно ли что-то подобное?