如何配置 wildfly 在 resteasy 中将 https 与 ClientBuilder 一起使用?

How to configure wildfly to use https with ClientBuilder in resteasy?

这是我第一次收到连接到 https url 的要求。很快,我就知道我需要 SSLContext 才能通过。

我也开始知道我需要在standalone.xml中进行配置才能完成。

任何指向 solution/link 工作代码的指针都将不胜感激。

我们必须自己生成密钥库吗?或 wildfly 提供任何现有的?

这是我试过的:

    SSLContext context = null;
    KeyManagerFactory kmf = null;
    KeyStore ks = null;
    char[] storepass = "somestringhere".toCharArray();
    char[] keypass = "somestringhere".toCharArray();

    try {
        context = SSLContext.getInstance("SSL");
    } catch (NoSuchAlgorithmException e3) {
        // TODO Auto-generated catch block
        e3.printStackTrace();
    }
    try {
        kmf = KeyManagerFactory.getInstance("SunX509");
    } catch (NoSuchAlgorithmException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    FileInputStream fin = null;
    try {
        fin = new FileInputStream("file here");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        ks = KeyStore.getInstance("JKS");
    } catch (KeyStoreException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        ks.load(fin, storepass);
    } catch (NoSuchAlgorithmException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (CertificateException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    try {
        kmf.init(ks, keypass);
    } catch (UnrecoverableKeyException | KeyStoreException | NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        context.init(kmf.getKeyManagers(), null, null);
    } catch (KeyManagementException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Client client = ClientBuilder.newBuilder().sslContext(context).build();

    WebTarget target = client
            .target("https://....");

    Builder builder = target.request();

我试了https://whosebug.com,它给了200OK,我试了google.com,它说文档已经移动了302状态。我尝试了我想要连接的 url 我得到了 peer not authenticated exception

Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:421) [jsse.jar:1.7.0_71]
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) [httpclient-4.2.5.jar:4.2.5]
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) [httpclient-4.2.5.jar:4.2.5]
    at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283) [resteasy-client-3.0.6.Final.jar:]
    ... 30 more

而且服务器要求基本认证,是不是异常的原因?

"Do we have to generate keystores ourselves?"

是的。需要为Server 和Trust store 生成一个(也就是key store,我们只是叫它trust store 来区别)

请参阅 Wildfly 文档中的 SSL setup guide。它将向您展示如何创建密钥库并使用 Wildfly 配置它。只需按照 "Pure Java SSL-Setup using keytool"

部分

然后您需要创建客户端密钥库。您将从服务器存储中导出证书并将其导入到客户端存储中。

它的工作原理是 Client 需要信任服务器。而做到这一点的方法是通过服务器证书。现在如果证书是由知名 CA 签发的,通常 Java 已经支持该证书,我们不需要配置客户端。但是由于您要创建自己的自签名证书,我们需要将客户端配置为通过将服务器证书导入信任库来信任它。

您可以在此处 查看为客户端 服务器处理 certs/stores 的所有步骤。向下滚动到第 5 步。以 keytool 开头的三个代码片段是完成此任务的命令。第一个创建名为 tomcat-keystore.jks 的服务器存储(但您可以随意命名)。下一个片段将证书从密钥库导出到一个文件名 tomcat.crt(但你可以随意命名)。第三个命令会将之前的证书导入 client-truststore.jks (但您可以随意命名)。您会注意到您不需要显式创建信任库,它会在我们进行导入时隐式创建。

获得服务器密钥库后,按照上面链接的 wildfly 文档中的说明使用服务器配置存储。

要配置 Client,请参阅上面链接的答案中的第 6 步。它使用我们创建的信任库配置客户端。代码中的所有内容都是标准的 Java 和 JAX-RS,除了 Basic auth 的配置,这是 Jersey 特有的。

这是我使用 Wildly 10.Note 将 JAX-RS 与 HTTPS 结合使用的代码,JAX-RS 的 Wildly 实现是 RestEasy 3.xxxx.

ClientBuilder builder = ClientBuilder.newBuilder();
builder.sslContext(ConnectionFactory.getSslContext());
builder.hostnameVerifier(ConnectionFactory.getHostnameVerifier());
client = builder.build();
String baseURI = acsUser.getSelectedService().getWebserviceBaseUrl();
WebTarget webTarget = client.target(baseURI);

这里是 class 调用的 ConnectionFactory。

public class ConnectionFactory {

Proxy proxy;

String proxyHost;

Integer proxyPort;

public boolean canConnect = true;

private static final Logger log = Logger.getLogger("ReportPortal");

public ConnectionFactory() {
}

/**
 *
 * @return
 */
public static SSLContext getSslContext() {
    SSLContext sslContext = null;
    try {
        sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new TrustManager[]{new      SecureTrustManager()}, new SecureRandom());
    }
    catch (NoSuchAlgorithmException | KeyManagementException ex) {
        log.error("ERROR OCCURS", ex);
    }
    return sslContext;
}

/**
 *
 * @return
 */
public static HostnameVerifier getHostnameVerifier() {
    return (String hostname, javax.net.ssl.SSLSession sslSession) -> true;
}

public Boolean isHttps(String url) {

    if (url.startsWith("https://")) {
        return Boolean.TRUE;
    }
    else {
        return Boolean.FALSE;
    }
}

}