如何将安全的 Jersey 应用程序部署到 Heroku

How to deploy secure Jersey application to Heroku

很容易弄清楚如何将使用 Grizzly 的 Jersey 应用程序部署到 Heroku。启动基本应用程序后,我决定按照 https-clientserver-grizzly 示例中的说明来保护我的端点,但在将其部署到 Heroku 时遇到一些问题 运行。

部署到 Heroku 后,服务器拒绝响应,关闭所有连接请求而不发送响应。我在本地没有问题,只有当我部署到 Heroku 时才会出现此错误。

我在下面包含了我的 Server.java 文件的相关部分。

public class Server extends ResourceConfig {
    private static final String DEFAULT_SERVER_PORT = "8443";
    private static final String KEY_SERVER_PORT = "server.port";
    private static final String KEY_TRUST_PASSWORD = "TRUST_PASSWORD";
    private static final String KEYSTORE_SERVER_FILE = "./security/keystore_server";
    private static final String LOCALHOST = "https://0.0.0.0:%s/v1";
    private static final String TRUSTSTORE_SERVER_FILE = "./security/truststore_server";

    private final String endpoint;
    private final HttpServer httpServer;

    private Server(final String endpoint) throws KeyManagementException, 
            NoSuchAlgorithmException, KeyStoreException, CertificateException,
            FileNotFoundException, IOException, UnrecoverableKeyException {
        super();

        ...

        URI.create(this.endpoint),
                this,
                true,
                secure());

        this.httpServer.start();

        System.out.println(String.format(
                "Jersey app started with WADL available at %s/application.wadl",
                this.endpoint));
    }


    /**
     * Generates a secure configurator for the server.
     * @return A {@link SSLEngineConfigurator} instance for the server.
     * @throws IOException If the key or trust store password cannot be read.
     * @throws RuntimeException If the configuration is considered invalid.
     */
    private static SSLEngineConfigurator secure() throws IOException, RuntimeException {
        // Set up security context
        final String password = System.getenv(KEY_TRUST_PASSWORD);
        if (password == null) {
            throw new RuntimeException("Truststore password is not set in the environment");
        }

        // Grizzly ssl configuration
        SSLContextConfigurator sslContext = new SSLContextConfigurator();

        // set up security context
        sslContext.setKeyStoreFile(KEYSTORE_SERVER_FILE); // contains server keypair
        sslContext.setKeyStorePass(password);
        sslContext.setTrustStoreFile(TRUSTSTORE_SERVER_FILE); // contains client certificate
        sslContext.setTrustStorePass(password);
        sslContext.setSecurityProtocol("TLS");

        if (!sslContext.validateConfiguration(true)) {
            throw new RuntimeException("SSL context is invalid");
        }

        return new SSLEngineConfigurator(sslContext)
                .setClientMode(false)
                .setNeedClientAuth(false);
    }
}

如果有人经历过这个问题并有任何建议,我们将不胜感激!

在 Heroku 上,您不需要自己在 Java 应用程序中设置 HTTPS。 Heroku 为您处理 HTTPS,SSL 终止发生在 Heroku 路由器上,因此流量在到达您的应用程序时未加密。

只需以 https:// 访问您的站点。herokuapp.com