关闭JGit clone命令的SSL验证

Yog*_*h_D 7 jgit

我试图通过它克隆一个Git存储库CloneCommand.有了这段代码

`Git.cloneRepository().setDirectory(new File(path)).setURI(url).call();`
Run Code Online (Sandbox Code Playgroud)

远程存储库位于使用自签名证书的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)
Run Code Online (Sandbox Code Playgroud)

虽然我可以创建一个新的TrustManager,但是注册一个虚拟对象HostnameVerifierSSLContext使用这个虚拟对象创建和初始化TrustManager.克隆完成后,还原所有这些.

但是,这意味着在同一时间启动的任何其他SSL连接都会将它们暴露给不安全的连接.

在已经克隆的仓库中,您可以将http.sslVerify设置为false,并且JGit可以正常工作.

是否有一种更清晰的方式,我可以告诉JGit将此http.sslVerify设置为false以进行克隆操作,就像我可以为已经克隆的回购做的那样.

Rüd*_*ann 8

使用4.9版本,JGit将更优雅地处理SSL验证.如果SSL握手不成功,JGit将询问CredentialsProvider是否应跳过SSL验证.

在这个过程中,CredentialsProvider被赋予了InformationalMessage所描述的问题以文字和最多三个YesNoType CredentialItems到决定是否跳过SSL验证这一操作,对于当前的存储库,和/或始终.

似乎更改是在交互式UI中进行的,并且可能很难以编程方式回答这些"凭据请求".

此更改提交消息更详细地描述了该行为.

对于早期版本的JGit,或者如果CredentialsProvider模型不符合您的需求,下面将介绍两种解决方法.


要解决此限制,您可以按照以下注释中的建议手动执行特定的克隆步骤:

  • 使用InitCommand初始化存储库
  • 将ssl verify设置为false
    StoredConfig config = git.getRepository().getConfig();
    config.setBoolean( "http", null, "sslVerify", false );
    config.save();
Run Code Online (Sandbox Code Playgroud)
  • fetch(参见FetchCommand)
  • 结帐(参见CheckoutCommand)

解决此问题的另一种方法是提供一个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;
  }
}
Run Code Online (Sandbox Code Playgroud)

HttpConnection在包中org.eclipse.jgit.transport.http,是HTTP连接的JGit抽象.虽然该示例使用默认实现(由JDK http代码支持),但您可以自由使用自己的实现或org.eclipse.jgit.transport.http.apache使用Apache http组件的包提供的实现.

可以使用以下命令更改当前使用的连接工厂HttpTransport::setConnectionFactory():

HttpConnectionFactory preservedConnectionFactory = HttpTransport.getConnectionFactory();
HttpTransport.setConnectionFactory( new InsecureHttpConnectionFactory() );
// clone repository
HttpTransport.setConnectionFactory( preservedConnectionFactory );
Run Code Online (Sandbox Code Playgroud)

不幸的是,连接工厂是一个单例,因此当同时执行JGit命令时,这个技巧需要额外的工作(例如,一个线程局部变量来控制sslVerify是打开还是关闭).


Jad*_*tos 6

另一种解决方法是.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();
}
Run Code Online (Sandbox Code Playgroud)

这将使 JGit 跳过 SSL 证书验证。

  • 我推荐使用 JGit API 来操作 Git 用户设置,使用 `SystemReader.getInstance().openUserConfig(null, FS.DETECTED)` 来获取一个 `FileBasedConfig` 可以用来操作和保存配置设置。 (3认同)