旧的共享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方法
现在,我们在通过弹簧靴嵌入式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)));
}
}
问题
这很好用-新的Spring Boot应用程序会将所有传入请求重定向到IdP进行身份验证,然后将SAML响应发回到原始请求的URL,然后按预期加载页面。
问题是,我们启用了需要绕过身份验证的弹簧启动执行器端点。具体来说,我们需要对健康检查端点/actuator/health
进行不安全保护,以便可以将其用作kubernetes的就绪探针。
我无法确定一种基于每个请求路径来应用ServletSecurity
的方法,因此我们不需要对对/actuator/*
路径的任何请求进行任何身份验证。
这样可能吗?
答案 0 :(得分:0)
找到了一个非常简单的解决方案。
如果将management.server.port
属性更改为与运行主应用程序上下文不同的端口,spring boot将自动为执行器端点创建子应用程序上下文。
这样,我添加的ServletSecurity
仅应用于默认的父应用程序上下文,并且在其他端口上运行的执行器端点不需要身份验证。