我们使用的解决方案非常干净、简单,并且在浏览器和操作系统之间可移植——使用代理服务器来处理SSL握手。您可以在运行测试的同一JVM中设置一个内存中的中间人代理服务器,或者甚至在不同端口上设置多个实例,每个实例分配给不同的客户端证书。然后,在创建WebDriver实例时,使用适合您的浏览器的
setProxy method。请注意,浏览器将显示安装在代理本身上的服务器证书,而不是目标服务器,因此可能会出现一些无效的证书错误,应在WebDriver设置中抑制这些错误。或者,如果您拥有密钥,则代理可以简单地使用有效的服务器证书,这样连接对于测试脚本就是完全透明的。Java中提供了一个满足要求的简单代理服务器
LittleProxy。也许像
BrowserMob这样的东西提供了更完整的解决方案,具有现成的API。使用LittleProxy的示例只需要几十行样板代码。
步骤1:
使用客户端证书(例如p12文件或PEM文件),扩展org.littleshoot.proxy.MitmManager
类,将其插入您的代码中。公开可用的工作示例在this repo。
步骤2:
使用您选择的客户端证书和服务器证书启动代理服务器:
org.littleshoot.proxy.impl.DefaultHttpProxyServer.DefaultHttpProxyServer.bootstrap()
.withIdleConnectionTimeout(FIVE_MINUTES)
.withName(clientCertFile.getName())
.withPort(port)
.withAllowLocalOnly(localConnectionOnly)
.withManInTheMiddle(new MutualAuthenticationCapableMitmManager(
usingPKCS12File(clientCertFile, clientCertPassword),
usingPemKeyPair(serverKeyPair[0], serverKeyPair[1])))
.start();
为每个需要重用相同端口的客户端证书创建另一个代理,或者启动并发实例。
步骤3:
使用代理启动WebDriver。主要浏览器(IE,Firefox,Chrome)以类似的方式支持此设置:
org.openqa.selenium.Proxy proxy = new Proxy();
proxy.setSslProxy("127.0.0.1:5555");
proxy.setNoProxy("<-loopback>");
FirefoxOptions options = new FirefoxOptions();
options.setProxy(proxy);
WebDriver driver = new FirefoxDriver(options);
第四步:
运行测试时,浏览器将不会打扰您任何证书提示。利润。
如果使用这种技术,请特别小心保护机密,并确保代理服务器本身对第三方不可达。在安全的公司网络之外泄露密钥绝不是一个好主意,无论它们是真实的还是虚假的。
SSLContexts.custom().loadTrustMaterial(new File(PATH), PASSWORD, new TrustSelfSignedStrategy()).build();
? 这会返回一个 SSLContext。如果这种方法可行的话,我可以帮你,我之前用 Selenium 做过自签名证书的 SSL。参考:https://www.programcreek.com/java-api-examples/index.php?api=org.apache.http.impl.conn.PoolingHttpClientConnectionManager (例子 2)。 - Bob