java - 通过 HTTPS 的 RESTful Web 服务

标签 java rest web-services tomcat ssl

我已经通过 Let's Encrypt 扩展在 Plesk 中为我的域安装了 SSL 证书。 HTTPS 的默认端口是 443。它工作正常。

现在我想在 Tomcat 7 上安装证书。我遵循了这个答案 https://community.letsencrypt.org/t/how-to-use-the-certificate-for-tomcat/3677/2创建一个 JKS keystore (来自 Plesk 中使用的相同的 Let's Encrypt 证书)并在不同的端口 445 上配置 Tomcat 的连接器。 当我在浏览器 (https://mywebsite.com:445) 上打开 tomcat 页面时,该页面是安全的。

问题是当我尝试使用以下 java 客户端连接到它时

public static void main(String[] args) {

  try {

    URL url = new URL("https://mywebsite.com:445");
    HttpsURLConnection  conn = (HttpsURLConnection ) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Accept", "text/plain");

    if (conn.getResponseCode() != 200) {
        throw new RuntimeException("Failed : HTTP error code : "
                + conn.getResponseCode());
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(
        (conn.getInputStream())));

    String output;
    System.out.println("Output from Server .... \n");
    while ((output = br.readLine()) != null) {
        System.out.println(output);
    }

    conn.disconnect();

  } catch (MalformedURLException e) {

    e.printStackTrace();

  } catch (IOException e) {

    e.printStackTrace();

  }

}

结果是异常(但如果我尝试 (https://mywebsite.com:443) 它有效)

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
    at main.NetClient.print_https_cert(NetClient.java:98)
    at main.NetClient.testIt(NetClient.java:79)
    at main.NetClient.main(NetClient.java:66)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    ... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 23 more
****** Content of the URL ********
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection$10.run(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection$10.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
    at main.NetClient.print_content(NetClient.java:131)
    at main.NetClient.testIt(NetClient.java:82)
    at main.NetClient.main(NetClient.java:66)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
    at main.NetClient.print_https_cert(NetClient.java:98)
    at main.NetClient.testIt(NetClient.java:79)
    ... 1 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    ... 17 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)
    ... 23 more

我需要通过 HTTPS 访问我的 RESTful Web 服务的资源。 请帮我。 提前致谢。

最佳答案

从 JAVA_HOME 备份您的 cacert:

$cp $JAVA_HOME/jre/lib/security/cacerts $JAVA_HOME/jre/lib/security/jssecacerts

然后从您的服务导入证书。

$keytool -import -trustcacerts -keystore $JAVA_HOME/jre/lib/security/jssecacerts -storepass
changeit -noprompt -alias {cert alias} -file {cert file}

然后重新启动您的应用。

关于java - 通过 HTTPS 的 RESTful Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46836614/

相关文章:

java - 声明这些变量在风格上最正确的方法是什么?

java - 如何在速度模板中将字符串转换为日期?

java - 无法转换类型“$Proxy55”的值

java - SOAPHandler JAX-WS WebService 中的 MessageContext

java - 服务和电信要求

java - 在 ubuntu 上安装 java...我的 java 主页是什么?

java - Java REST WS 中的 POST header 问题

java - Struts 上的 Rest API

api - 用于添加/删除数组元素的 RESTful API 端点?

c# - 如何使用C#在POST请求中发送json数据