java - 在 Java 中使用 HTTPS 和 REST

标签 java rest ssl x509

我有一个用 Grizzly 制作的 REST 服务器,它使用 HTTPS 并与 Firefox 完美配合。代码如下:

//Build a new Servlet Adapter.
ServletAdapter adapter=new ServletAdapter();
adapter.addInitParameter("com.sun.jersey.config.property.packages", "My.services");
adapter.addInitParameter(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, SecurityFilter.class.getName());
adapter.setContextPath("/");
adapter.setServletInstance(new ServletContainer());

//Configure SSL (See instructions at the top of this file on how these files are generated.)
SSLConfig ssl=new SSLConfig();
String keystoreFile=Main.class.getResource("resources/keystore_server.jks").toURI().getPath();
System.out.printf("Using keystore at: %s.",keystoreFile);
ssl.setKeyStoreFile(keystoreFile);
ssl.setKeyStorePass("asdfgh");

//Build the web server.
GrizzlyWebServer webServer=new GrizzlyWebServer(getPort(9999),".",true);

//Add the servlet.
webServer.addGrizzlyAdapter(adapter, new String[]{"/"});

//Set SSL
webServer.setSSLConfig(ssl);

//Start it up.
System.out.println(String.format("Jersey app started with WADL available at "
  + "%sapplication.wadl\n",
        "https://localhost:9999/"));
webServer.start();

现在,我尝试用 Java 实现它:

SSLContext ctx=null;
try {
    ctx = SSLContext.getInstance("SSL");
} catch (NoSuchAlgorithmException e1) {
    e1.printStackTrace();
}
ClientConfig config=new DefaultClientConfig();
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(null,ctx));
WebResource service=Client.create(new DefaultClientConfig()).resource("https://localhost:9999/");

//Attempt to view the user's page.
try{
    service
        .path("user/"+username)
        .get(String.class);
}

得到:

com.sun.jersey.api.client.ClientHandlerException: 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 com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:128)
 at com.sun.jersey.api.client.Client.handle(Client.java:453)
 at com.sun.jersey.api.client.WebResource.handle(WebResource.java:557)
 at com.sun.jersey.api.client.WebResource.get(WebResource.java:179)

从我在网上找到的示例来看,我似乎需要设置一个 Truststore,然后设置某种 TrustManager。对于我的简单小项目来说,这似乎有很多代码和设置工作。有没有更简单的方法可以说..我信任这个证书并指向一个 .cert 文件?

最佳答案

当您说“有没有更简单的方法来...信任此证书”时,这正是您通过将证书添加到 Java 信任库中所做的事情。这非常非常容易做到,您无需在客户端应用程序中执行任何操作即可让信任库得到认可或利用。

在您的客户端计算机上,找到您的 cacerts 文件所在的位置(这是您的默认 Java 信任库,默认情况下位于 /lib/security/certs/cacerts。

然后,输入以下内容:

keytool -import -alias <Name for the cert> -file <the .cer file> -keystore <path to cacerts>

这会将证书导入您的信任存储区,之后,您的客户端应用将能够毫无问题地连接到您的 Grizzly HTTPS 服务器。

如果您不想将证书导入您的默认信任存储区——即,您只希望它可用于这个客户端应用程序,而不是您在该机器上的 JVM 上运行的任何其他应用程序——然后您可以为您的应用创建一个新的信任库。不要将 keytool 传递到现有的默认 cacerts 文件的路径,而是将 keytool 传递到新的信任库文件的路径:

keytool -import -alias <Name for the cert> -file <the .cer file> -keystore <path to new trust store>

系统将要求您设置并验证信任存储文件的新密码。然后,当您启动客户端应用程序时,使用以下参数启动它:

java -Djavax.net.ssl.trustStore=<path to new trust store> -Djavax.net.ssl.trustStorePassword=<trust store password>

简单俗气,真的。

关于java - 在 Java 中使用 HTTPS 和 REST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1757295/

相关文章:

java - Log4j 自定义 Appender 最初抛出 ClassNotFoundException?

java - 什么是 java.constructors.single()?

c# - 使用 WCF 生成 JSON 数组

html - 为什么我的 https 站点 url 是红色的,尽管我已经配置并使其安全

java - 如何按已合并的 2 个列表的 id 对元素进行排序?

java - 保存电子邮件附件

java - 在 SpringBoot 应用之外使用 MockMVC

java - 使用 Jersey 测试 RESTful Web 服务时出现 HTTP 状态 404

node.js - 无法使用 nginx 在快速服务器之上配置 SSL

ssl - 如何在 ehcache 中配置 RMI over SSL 进行复制