Spring Boot 2 - AJP

8
我在我的Spring Boot 2项目中添加了一个AJP连接器。
 @Bean
 public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new 
   TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(redirectConnector());

        return tomcat;
    }

    private Connector redirectConnector() {
        Connector connector = new Connector("AJP/1.3");
        connector.setScheme("http");
        connector.setPort(ajpPort);
        connector.setSecure(false);
        connector.setAllowTrace(false);
        return connector;
    }

这个很好用。我现在可以通过我的Apache Web服务器访问我的Spring Boot应用程序。但是,如果我运行我的Spring Boot应用程序,我就不能直接访问它了。所以这个URL不再起作用。

http://localhost:13080/online/showlogin?m=test

如果我禁用AJP连接器,URL就会再次起作用。我已经尝试过以下方法。
 private Connector redirectConnector2() {
    Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
    connector.setScheme("http");
    connector.setPort(13080);
    connector.setSecure(false);
    connector.setAllowTrace(false);
    return connector;
}
...
tomcat.addAdditionalTomcatConnectors(redirectConnector2());
...

但这对我没有帮助。


不要创建一个 TomcatServletWebServerFactory,而是创建一个 WebServerFactoryCustomizer<TomcatServletWebServerFactory>,它将添加 AJP 相关内容。这将在 Spring Boot 的默认配置之外执行。 - M. Deinum
2个回答

14

这对我有用:

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainer() {
      return server -> {
        if (server instanceof TomcatServletWebServerFactory) {
            ((TomcatServletWebServerFactory) server).addAdditionalTomcatConnectors(redirectConnector());
        }
      };
    }

    private Connector redirectConnector() {
       Connector connector = new Connector("AJP/1.3");
       connector.setScheme("http");
       connector.setPort(ajpPort);
       connector.setSecure(false);
       connector.setAllowTrace(false);
       return connector;
    }

7
我们成功使用tomas answers的代码很长一段时间,但在升级到Spring Boot版本>2.2.4后,它停止工作了。我们在启动时收到了以下错误信息:

应用程序启动失败

描述:

配置为监听端口1234的Tomcat连接器启动失败。该端口可能已被使用或连接器可能配置不正确。

操作:

验证连接器的配置,识别并停止任何在端口1234上监听的进程,或将此应用程序配置为侦听另一个端口。

但是该端口没有被使用,那么问题是什么?

这个问题是由包含在Spring Boot 2.2.5中的AJP中Tomcat的 Ghostcat漏洞修复引起的。

现在你有两个选择,要么使用带有密钥的AJP:

final Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(ajpPort);
connector.setAllowTrace(false);

final AbstractAjpProtocol protocol = (AbstractAjpProtocol) connector.getProtocolHandler();
connector.setSecure(true);
protocol.setSecret(ajpSecret);

或者不需要一个,但是为了这个你必须明确地将setSecretRequired设置为false

final Connector connector = new Connector("AJP/1.3");
connector.setScheme("http");
connector.setPort(ajpPort);
connector.setAllowTrace(false);

final AbstractAjpProtocol protocol = (AbstractAjpProtocol) connector.getProtocolHandler();
connector.setSecure(false);
protocol.setSecretRequired(false);

注意: 后面的解决方案会让你的Tomcat再次容易受到Ghostcat攻击。

欲了解更多信息,请查看此线程: Springboot - 升级到2.2.5后,AJP连接器配置为secretRequired="true",但secret属性为空或""


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接