使用Jersey Client忽略自签名的ssl证书

Chr*_*lij 61 java ssl jersey ssl-certificate

我正在使用Jersey Client库对运行在jboss上的休息服务运行测试.我使用自签名证书在服务器上运行https(在localhost上运行).

但是每当我使用https url运行测试时,我都会收到以下错误:

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:131)
    at com.sun.jersey.api.client.Client.handle(Client.java:629)
    at com.sun.jersey.oauth.client.OAuthClientFilter.handle(OAuthClientFilter.java:137)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:601)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
    at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:459)
    at test.helper.Helper.sendSignedRequest(Helper.java:174)
    ... And so on
Run Code Online (Sandbox Code Playgroud)

我知道这是因为我的自签名证书不在java密钥库中.我有什么方法可以Client不检查ssl证书的有效性,并且无论如何都使用它?

此代码将仅针对测试服务器运行,因此我不想在每次设置新测试服务器时都不必添加新的可信证书.

这是拨打电话的代码:

OAuthParameters params = new OAuthParameters();

// baseline OAuth parameters for access to resource
params.signatureMethod(props.getProperty("signature_method"));
params.consumerKey(props.getProperty("consumer_key"));
params.setToken(props.getProperty("token"));
params.setVersion("1.0");
params.nonce();

// OAuth secrets to access resource
OAuthSecrets secrets = new OAuthSecrets();
secrets.consumerSecret(props.getProperty("consumer_secret"));
secrets.setTokenSecret(props.getProperty("token_secret"));

// Jersey client to make REST calls to token services
Client client = Client.create();

// OAuth test server resource
WebResource resource = client.resource(props.getProperty("url"));

// if parameters and secrets remain static, filter cab be added to each web resource
OAuthClientFilter filter = new OAuthClientFilter(client.getProviders(), params, secrets);

// filter added at the web resource level
resource.addFilter(filter);
WebResource.Builder wbr = resource.getRequestBuilder().accept(props.getProperty("accept"));

return wbr.get(ClientResponse.class);
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.

Chr*_*lij 90

经过一些旧的stackoverflow问题的搜索和搜索后,我在之前提出的SO问题中找到了一个解决方案:

这是我最终使用的代码.

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
    public X509Certificate[] getAcceptedIssuers(){return null;}
    public void checkClientTrusted(X509Certificate[] certs, String authType){}
    public void checkServerTrusted(X509Certificate[] certs, String authType){}
}};

// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
    ;
}
Run Code Online (Sandbox Code Playgroud)

  • 我不得不用`public X509Certificate [] getAcceptedIssuers(){return new X509Certificate [0];}`替换`public X509Certificate [] getAcceptedIssuers(){return null;}`以使它工作. (8认同)
  • 这个答案在Java中设置*all*HTTPS连接以忽略SSL证书...这可能不是你想要的,因为它可能只针对有问题的客户端,如@eitan和其他人的另一个答案所示. (6认同)

eit*_*tan 58

对于Jersey 2.*(在2.7上测试)和java 8:

import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 

public static Client ignoreSSLClient() throws Exception {

    SSLContext sslcontext = SSLContext.getInstance("TLS");

    sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
    }}, new java.security.SecureRandom());

    return ClientBuilder.newBuilder()
                        .sslContext(sslcontext)
                        .hostnameVerifier((s1, s2) -> true)
                        .build();
}
Run Code Online (Sandbox Code Playgroud)

  • 从哪里导入包?java还是javax? (4认同)
  • 导入 java.security.cert.CertificateException; 导入 java.security.cert.X509Certificate; 导入 javax.net.ssl.SSLContext; 导入 javax.net.ssl.TrustManager; 导入 javax.net.ssl.X509TrustManager; (2认同)

Ran*_*ggs 12

我有同样的问题,adn不希望全局设置,所以我使用了与上面相同的TrustManager和SSLContext代码,我只是改变了用特殊属性创建的客户端

 ClientConfig config = new DefaultClientConfig();
 config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
     new HostnameVerifier() {
         @Override
         public boolean verify( String s, SSLSession sslSession ) {
             // whatever your matching policy states
         }
     }
 ));
 Client client = Client.create(config);
Run Code Online (Sandbox Code Playgroud)


Bru*_*uno 8

此代码将仅针对测试服务器运行,因此我不想在每次设置新测试服务器时都不必添加新的可信证书.

这种代码最终会在生产中找到它的方式(如果不是您,那么正在阅读此问题的其他人会将已经建议的不安全信任管理器复制并粘贴到他们的应用程序中).当你有一个截止日期时,忘记删除这类代码是非常容易的,因为它不会显示为问题.

如果您担心每次拥有测试服务器时都必须添加新证书,请创建自己的小型CA,使用该CA颁发测试服务器的所有证书,并将此CA证书导入客户端信任库.(即使您没有在本地环境中处理诸如在线证书撤销之类的事情,这肯定比使用信任管理器更好.)

有一些工具可以帮助您做到这一点,例如TinyCAXCA.


Muk*_*esh 8

由于我是stackoverflow的新手并且对其他人的答案发表评论的声誉较低,因此我将Chris Salij建议的解决方案作为一些修改对我有用.

            SSLContext ctx = null;
            TrustManager[] trustAllCerts = new X509TrustManager[]{new X509TrustManager(){
                public X509Certificate[] getAcceptedIssuers(){return null;}
                public void checkClientTrusted(X509Certificate[] certs, String authType){}
                public void checkServerTrusted(X509Certificate[] certs, String authType){}
            }};
            try {
                ctx = SSLContext.getInstance("SSL");
                ctx.init(null, trustAllCerts, null);
            } catch (NoSuchAlgorithmException | KeyManagementException e) {
                LOGGER.info("Error loading ssl context {}", e.getMessage());
            }

            SSLContext.setDefault(ctx);
Run Code Online (Sandbox Code Playgroud)


mas*_*asi 6

对于 Jersey 2.x 上没有 lambdas 的任何人,请使用以下命令:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

public static Client getUnsecureClient() throws Exception 
{
    SSLContext sslcontext = SSLContext.getInstance("TLS");
    sslcontext.init(null, new TrustManager[]{new X509TrustManager() 
    {
            public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}
            public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{}
            public X509Certificate[] getAcceptedIssuers()
            {
                return new X509Certificate[0];
            }

    }}, new java.security.SecureRandom());


    HostnameVerifier allowAll = new HostnameVerifier() 
    {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(allowAll).build();
}
Run Code Online (Sandbox Code Playgroud)

JRE 1.7上使用jersey-client 2.11进行测试。


归档时间:

查看次数:

143571 次

最近记录:

6 年,6 月 前