抱歉,你查看的文章不存在

htmlunit 解决https证书不信任问题

代码如下

@Test
    public void testHtmlUnit() throws Exception {
        WebClient client = new WebClient(BrowserVersion.CHROME);
//        client.getOptions().setUseInsecureSSL(true);
        HtmlPage page = client.getPage("https://10.167.33.50/user");
        HtmlElement username = page.getElementByName("usrname");
        username.type("ns25000");
        HtmlElement pwd = page.getElementByName("pass");
        pwd.type("ns25000");
        page.executeJavaScript("submitbutton('login','loginForm');");
        System.out.print(page.getWebResponse().getContentAsString());
    }

运行错误如下

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.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:261)
at com.gargoylesoftware.htmlunit.HtmlUnitSSLConnectionSocketFactory.connectSocket(HtmlUnitSSLConnectionSocketFactory.java:155)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:118)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:357)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:218)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:178)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1313)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1230)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:338)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:407)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:392)
at com.fnst.es.test.TestEs.testHtmlUnit(TestEs.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
... 51 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 57 more

发现应当是https的证书过期或不受信任。google之,发现htmlunit也是采用httpclient,因此采用了httpclient的解决办法

SSLContext sslContext = SSLContext.getInstance("SSL");
// set up a TrustManager that trusts everything
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                    System.out.println("getAcceptedIssuers =============");
                    return null;
            }
            public void checkClientTrusted(X509Certificate[] certs,
                            String authType) {
                    System.out.println("checkClientTrusted =============");
            }
            public void checkServerTrusted(X509Certificate[] certs,
                            String authType) {
                    System.out.println("checkServerTrusted =============");
            }
} }, new SecureRandom());
SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);
// apache HttpClient version >4.2 should use BasicClientConnectionManage
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm);

以上答案无果……

继续谷歌之(大谷歌不能用,还有谷搜客

找到如下

how to ignore ssl certificate error

解决方案:

For future reference if someone wants to do the same thing its fairly straight forward.

1)Create a package called org.apache.commons.httpclient.contrib.ssl add the two files. EasySSLProtocolSocketFactory.java EasyX509TrustManager.java Compile.

2)Add the following lines of code to your htmlclient before making any htmlunit calls

Protocol easyhttps = new Protocol("https", new   
EasySSLProtocolSocketFactory(), 443);   
Protocol.registerProtocol("https", easyhttps);

对应两个java文件如下

http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java?view=markup

http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java?view=markup

按照修改后依旧不起作用

最后看到作者描述

FYI, starting with version 1.14 you can use WebClient.setUseInsecureSSL(true) instead, and it will take care of all the HttpClient configuration behind the scenes.

好激动……

使用是发现webclient没有此方法,原来已被提取自webclientoptions类中。

/**
 * If set to <code>true</code>, the client will accept connections to any host, regardless of
 * whether they have valid certificates or not. This is especially useful when you are trying to
 * connect to a server with expired or corrupt certificates.
 * @param useInsecureSSL whether or not to use insecure SSL
 */
public void setUseInsecureSSL(final boolean useInsecureSSL) {
    useInsecureSSL_ = useInsecureSSL;
}

因此将代码修改至

@Test
public void testHtmlUnit() throws Exception {
    WebClient client = new WebClient(BrowserVersion.CHROME);
    client.getOptions().setUseInsecureSSL(true);
    HtmlPage page = client.getPage("https://10.167.33.50/user");

    HtmlElement username = page.getElementByName("usrname");

    username.type("ns25000");

    HtmlElement pwd = page.getElementByName("pass");

    pwd.type("ns25000");

    page.executeJavaScript("submitbutton('login','loginForm');");
    System.out.print(page.getWebResponse().getContentAsString());
}

OK~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

后端之路

0 篇文章0 人订阅

相关文章

来自专栏移动开发

关于主线程中自动建立的Looper的思考:主线程中Looper中的轮询死循环为何没有阻塞主线程

Android中UI线程会自动给我们建立一个looper,但是looper中的loop方法是个死循环.为什么我们在UI线程中写的代码为何都能顺利执行?为什么没有...

2174
来自专栏一个会写诗的程序员的博客

SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required

java.sql.SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required at ...

4682
来自专栏流媒体人生

基于S3C6410和ffmpeg的视频加速示例

1054
来自专栏13blog.site

org.springframework.data.redis.serializer.SerializationException: Cannot serialize;

前言 本文中提到的解决方案,源码地址在:perfect-ssm,希望可以帮你解决问题。 问题描述 在Spring与Redis整合过程中,出现了如下报错: ...

5926
来自专栏移动开发面面观

Handler源码分析

1355
来自专栏技术小黑屋

Check if a Thread Is Main Thread in Android

How to check a certain thread is the main one or not in Android? You may say it ...

1311
来自专栏码云1024

c++ 平衡二叉树的实现

4315
来自专栏数据库新发现

在RAC环境中如何管理日志(redolog file)组

http://www.eygle.com/faq/How.To.Mangement.redologfile.in.Rac.Raw.htm

1032
来自专栏乐享123

Udp Packet Receive Errors

5865
来自专栏coding...

iOS开发实战-基于SpriteKit的FlappyBird小游戏写在前面SpriteKit简介效果分析代码关于游戏上架TipsDemo地址还没结束

蛋疼广电粽菊要求国内游戏必须备案... 我们只是想上个小游戏而已~难道还要再等个大半个月去备案么? Apple也妥协了 在备注那里要求中国区上架游戏必须填写...

1472

扫码关注云+社区

领取腾讯云代金券