旧的共享 Tomcat 方法
我有一个自定义的 SAML 2.0 身份验证阀,我目前在一些独立的 tomcat Web 服务器中使用它来实现单点登录。
为了实现这一点,我们将阀门添加到 tomcat 服务器的 context.xml 中,如下所示(使用一些示例值而不是实际值):
<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 嵌入式 Tomcat 方法
现在,我们在通过 spring boot 嵌入式 tomcat 运行的独立 spring boot 应用程序中使用这个阀门。我们通过 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)));
}
}
问题
这很好用——新的 Spring Boot 应用程序会将任何传入请求重定向到 IdP 以进行身份验证,然后 IdP 将 SAML 响应发布回最初请求的 URL,并且页面按预期加载。
问题是,我们启用了需要绕过该身份验证的 Spring Boot 执行器端点。具体来说,我们需要/actuator/health
不安全的健康检查端点,以便它可以用作 kubernetes 的就绪探测。
我无法确定ServletSecurity
在每个请求路径的基础上应用它的方法,因此我们不需要对/actuator/*
路径的任何请求进行任何身份验证。
这样的事情可能吗?