旧的共享Tomcat方法
我有一个定制的SAML 2.0身份验证阀,目前我在一些独立的tomcat web服务器中使用它来实现单点登录。
<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来控制哪些端点需要保护。
现在,我们在通过SpringBoot嵌入式tomcat运行的独立SpringBoot应用程序中使用这个阀门。我们通过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引导应用程序将把任何传入的请求重定向到IdP进行身份验证,IdP随后将SAML响应发送回最初请求的URL,并按预期加载页面。
/actuator/health
不安全的,因此它可以用作库伯内特斯的战备探测器。
我无法决定用什么方法
ServletSecurity
以每个请求路径为基础,这样我们就不需要对
/actuator/*
路径。