如何在Heroku应用程序上设置自定义SSLSocketFactory?

时间:2019-01-05 17:45:15

标签: java heroku sslsocketfactory

我想控制我的应用程序可以连接到哪个公共IP地址,以便可以将一小部分IP列入黑名单,以用于整个应用程序的传出连接。

将Tomcat Java应用程序部署到Heroku,我通过覆盖“ java.security.properties”来指定了自定义Java安全配置

web: java $JAVA_OPTS -Djava.security.properties=java.security -jar target/dependency/webapp-runner.jar --port $PORT target/*.war

在该配置中,我给了一个自定义SSLSocketFactory类

ssl.SocketFactory.provider=security.MyCustomSocketFactory

这使MyCustomSocketFactory可以在一个小型示例应用程序中检查每个IP地址和主机的传出连接。但是,在部署到Heroku之后,它不适用于完整的应用程序。即使将该类打包到.war文件中,也找不到该类。

Caused by: java.lang.ClassNotFoundException: security.MyCustomSocketFactory
 at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
 at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
 at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
 at java.base/javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:105)
 at java.base/javax.net.ssl.HttpsURLConnection.getDefaultSSLSocketFactory(HttpsURLConnection.java:335)
 at java.base/javax.net.ssl.HttpsURLConnection.<init>(HttpsURLConnection.java:292)

我想我必须指定我的单个类是不同的类加载的,因为我的应用程序是由webapp-runner.jar初始化的。我应该采取其他方法吗?

我知道我的课程可供某些类加载器使用,因为我可以从自己的代码中调用Class.forName(),而不会出现异常。但这只是无法从SSLSocketFactory.getDefault()加载。

1 个答案:

答案 0 :(得分:0)

正如评论中的codefinger suggested一样,我需要在war文件外部的类路径中包括MyCustomSocketFactory。

我将MyCustomSocketFactory移至一个单独的Maven项目,并将其构建为一个单独的jar。

然后,我在主项目中添加了一个内置步骤,将JAR复制到与webapp-runner.jar相同的目录中。

<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>copy-socketblocker</id>
            <phase>package</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
  <outputDirectory>${basedir}/target/dependency</outputDirectory>
                <resources>
                    <resource>
                        <directory>jars</directory>
                        <includes>socketblocker-1.0.jar</includes>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

最后,我修改了Procfile以使用通配符匹配,并将webapp-runner.jar和自定义JAR都添加为类路径条目。

web: java $JAVA_OPTS -Djava.security.properties=java.security -cp "target/dependency/*" webapp.runner.launch.Main --port $PORT target/*.war