在 Java 中将 HTTPS 与 REST 结合使用 [英] Using HTTPS with REST in Java

查看:29
本文介绍了在 Java 中将 HTTPS 与 REST 结合使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a REST server made in Grizzly that uses HTTPS and works wonderfully with Firefox. Here's the code:

//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
",
        "https://localhost:9999/"));
webServer.start();

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

Now, I try to reach it in 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 文件?

From examples that I've found on the web, it seems like I would need to setup a Truststore then setup some sort of TrustManager. This seems like a lot of code and setup work for my simple little project. Is there an easier way to just say..I trust this cert and point to a .cert file?

推荐答案

当您说有没有更简单的方法可以……信任此证书"时,这正是您通过将证书添加到 Java 信任所做的工作店铺.这非常非常容易,而且您无需在您的客户端应用程序中执行任何操作即可识别或利用该信任库.

When you say "is there an easier way to... trust this cert", that's exactly what you're doing by adding the cert to your Java trust store. And this is very, very easy to do, and there's nothing you need to do within your client app to get that trust store recognized or utilized.

在您的客户端计算机上,找到您的 cacerts 文件所在的位置(这是您的默认 Java 信任存储,默认情况下位于 <java-home>/lib/security/certs/cacerts.

On your client machine, find where your cacerts file is (that's your default Java trust store, and is, by default, located at <java-home>/lib/security/certs/cacerts.

然后,输入以下内容:

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

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

That will import the cert into your trust store, and after this, your client app will be able to connect to your Grizzly HTTPS server without issue.

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

If you don't want to import the cert into your default trust store -- i.e., you just want it to be available to this one client app, but not to anything else you run on your JVM on that machine -- then you can create a new trust store just for your app. Instead of passing keytool the path to the existing, default cacerts file, pass keytool the path to your new trust store file:

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

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

You'll be asked to set and verify a new password for the trust store file. Then, when you start your client app, start it with the following parameters:

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

简单俗气,真的.

这篇关于在 Java 中将 HTTPS 与 REST 结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆