我正试图通过CloneCommand
克隆一个Git Repository。
使用这段代码
`Git.cloneRepository().setDirectory(new File(path)).setURI(url).call();`
远程存储库位于使用自签名证书的GitBlit实例上。 由于这些自签名证书,我在克隆的获取部分执行时得到以下异常:
Caused by: java.security.cert.CertificateException: No name matching <hostName> found
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:221)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:95)
虽然我可以创建新的TrustManager
,但请注册虚拟HostnameVerifier
并创建并初始化使用此虚拟SSLContext
的{{1}}。
克隆完成后,还原所有这些。
但是,这意味着在同一时间启动的任何其他SSL连接都会将它们暴露给不安全的连接。
在已经克隆的仓库中,您可以将http.sslVerify设置为false,JGit可以正常工作。
有没有一种更清晰的方法可以告诉JGit将此http.sslVerify设置为false以进行克隆操作,就像我可以为已经克隆的回购做的那样。
答案 0 :(得分:8)
使用4.9版本,JGit将更优雅地处理SSL验证。如果是SSL
握手不成功,JGit会询问CredentialsProvider
是否应该跳过SSL验证。
在此过程中,CredentialsProvider
会以文本方式提供InformationalMessage
,最多三个YesNoType
CredentialItem
来决定是否跳过此操作的SSL验证,对于当前存储库,和/或始终。
似乎更改是在考虑交互式UI的情况下进行的,并且可能很难以编程方式回答这些“凭据请求”。
commit message of this change更详细地描述了行为。
对于早期版本的JGit,或者CredentialsProvider
模型不符合您的需求,下面介绍了两种解决方法。
要解决此限制,您可以手动执行特定克隆步骤,如以下评论中所示:
StoredConfig config = git.getRepository().getConfig();
config.setBoolean( "http", null, "sslVerify", false );
config.save();
解决此问题的另一种方法是提供HttpConnectionFactory
,返回带有虚拟主机名和证书验证程序的HttpConnection
。例如:
class InsecureHttpConnectionFactory implements HttpConnectionFactory {
@Override
public HttpConnection create( URL url ) throws IOException {
return create( url, null );
}
@Override
public HttpConnection create( URL url, Proxy proxy ) throws IOException {
HttpConnection connection = new JDKHttpConnectionFactory().create( url, proxy );
HttpSupport.disableSslVerify( connection );
return connection;
}
}
HttpConnection
位于包org.eclipse.jgit.transport.http
中,是HTTP连接的JGit抽象。虽然该示例使用默认实现(由JDK http代码支持),但您可以自由使用自己的实现或使用Apache http组件的org.eclipse.jgit.transport.http.apache
包提供的实现。
可以使用HttpTransport::setConnectionFactory()
更改当前使用的连接工厂:
HttpConnectionFactory preservedConnectionFactory = HttpTransport.getConnectionFactory();
HttpTransport.setConnectionFactory( new InsecureHttpConnectionFactory() );
// clone repository
HttpTransport.setConnectionFactory( preservedConnectionFactory );
不幸的是,连接工厂是一个单例,因此当同时执行JGit命令时,这个技巧需要额外的工作(例如,一个线程局部变量来控制sslVerify是打开还是关闭)。
答案 1 :(得分:4)
另一种解决方法是在调用.gitconfig
之前在当前用户的主目录中创建Git.cloneRepository()
文件:
File file = new File(System.getProperty("user.home")+"/.gitconfig");
if(!file.exists()) {
PrintWriter writer = new PrintWriter(file);
writer.println("[http]");
writer.println("sslverify = false");
writer.close();
}
这将使JGit跳过SSL证书验证。
答案 2 :(得分:0)
我从上面的所有答案中推断出以下代码段;
private void disableSSLVerify(URI gitServer) throws Exception {
if (gitServer.getScheme().equals("https")) {
FileBasedConfig config = SystemReader.getInstance().openUserConfig(null, FS.DETECTED);
synchronized (config) {
config.load();
config.setBoolean(
"http",
"https://" + gitServer.getHost() + ':' + (gitServer.getPort() == -1 ? 443 : gitServer.getPort()),
"sslVerify", false);
config.save();
}
}
}
此选项较为安全,因为它仅允许gitServer
的sslVerify为false。
请查看此链接,该链接与其他options共享。