有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Spring Boot嵌入式Tomcat中的java自定义SAML身份验证阀不适用于执行器端点

旧的共享Tomcat方法

我有一个定制的SAML2.0身份验证阀,我目前在一些独立的tomcat web服务器中使用它来实现单点登录

为了实现这一点,我们将阀门添加到tomcat服务器的上下文中。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引导应用程序将任何传入请求重定向到IdP进行身份验证,然后IdP将SAML响应发回最初请求的URL,页面按预期加载

问题是,我们启用了需要绕过该身份验证的spring引导执行器端点。具体地说,我们需要健康检查端点/actuator/health是不安全的,以便可以将其用作kubernetes的就绪探测

我无法确定在每个请求路径的基础上应用该ServletSecurity的方法,这样就不需要对/actuator/*路径的任何请求进行任何身份验证

这样的事情可能吗


共 (1) 个答案

  1. # 1 楼答案

    找到了一个非常简单的解决方案

    如果将management.server.port属性更改为与运行主应用程序上下文的端口不同的端口,spring boot将自动为执行器端点创建子应用程序上下文

    这样,我添加的ServletSecurity只应用于默认的父应用程序上下文,而在另一个端口上运行的执行器端点不需要身份验证