【问题标题】:How to configure wildfly to use https with ClientBuilder in resteasy?如何配置wildfly以在resteasy中将https与ClientBuilder一起使用?
【发布时间】:2015-08-20 01:39:54
【问题描述】:

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

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

任何指向解决方案/链接的指针,工作代码将不胜感激。

我们必须自己生成密钥库吗?还是 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://stackoverflow.com,它给了200OK,我试过google.com,它说文件已经移动302状态。我尝试了我想连接的 url 我得到了 peer not authenticated 异常

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

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

【问题讨论】:

    标签: java ssl jax-rs resteasy wildfly


    【解决方案1】:

    “我们必须自己生成密钥库吗?”

    是的。您需要为服务器和信任存储生成一个(这只是一个密钥存储,但我们只是将其称为信任存储以区分它)。

    请参阅 Wildfly 文档中的 SSL setup guide。它将向您展示如何创建密钥库并使用 Wildfly 对其进行配置。只需按照“使用 keytool 的纯 Java SSL 设置”部分进行操作

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

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

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

    获得服务器密钥库后,请按照上面链接的 Wildfly 文档中的说明进行操作,并使用服务器配置存储。

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

    【讨论】:

    • 我正在连接 https url,但该 url 不是我的……我的意思不是来自我的 jax-rs 应用程序……我只想使用 ClientBuilder api 连接到该 url……所以在这个情况下,我不需要用证书配置wildfly服务器吗?因为我不想托管任何 https 连接?
    • 对不起,我以为你想从你的服务器和客户端做一些测试。如果您正在访问的服务器具有由知名 CA 签名的证书,则 Java 很可能在其自己的信任库中拥有该证书,您无需对其进行配置。假设您想访问 Google API。信任库中肯定会有证书,您不需要配置客户端。仅当证书不受信任时才需要这样做。您可以尝试向服务器发出 https 请求,看看会发生什么。如果证书不受信任,您可以忽略不受信任的证书,或者下载并添加它
    • 我可能会在这两种情况下为您找到一些很好的信息,但首先您应该检查它是否已经适用于您尝试访问的网址。
    • 在这种情况下,我应该通过哪个 SSLConext?我尝试使用 getDefault 它不起作用。我的对等方未通过身份验证。我遇到麻烦的部分是使用密钥库和所有初始化 sslcontext。但是不能假设服务器的证书是有效的并且可以通过身份验证吗?
    • 基本上你只需要SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null);。将tmf.getTrustManagers() 替换为来自github 的TrustManager[]。然后你可以做ClientBuilder.newBuilder().sslContext(sslContext).hostNameVerifier(hostNameVierifer)
    【解决方案2】:

    这是我使用 Wildly 10 将 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);
    

    这是一个名为 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;
        }
    }
    

    }

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-10
    • 2021-07-24
    • 1970-01-01
    • 2016-06-06
    • 2019-01-09
    • 2011-04-07
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多