代码之家  ›  专栏  ›  技术社区  ›  Andrew Mairose

Spring Boot Embedded Tomcat中的自定义SAML身份验证阀-不适用于执行器端点

  •  0
  • Andrew Mairose  · 技术社区  · 8 年前

    旧的共享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/* 路径。

    1 回复  |  直到 8 年前
        1
  •  0
  •   Andrew Mairose    8 年前

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

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

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

    推荐文章