jgit - 为 JGit 克隆命令关闭 SSL 验证

标签 jgit

我正在尝试通过 CloneCommand 克隆 Git 存储库.
用这段代码

`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使用这个假人 TrustManager .
克隆完成后,还原所有这些。

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

在已经克隆的 repo 上,您可以将 http.sslVerify 设置为 false 并且 JGit 工作得很好。

是否有一种更简洁的方法可以告诉 JGit 将此 http.sslVerify 设置为 false 以进行克隆操作,就像我可以为已经克隆的存储库做的那样。

最佳答案

在 4.9 版本中,JGit 将更优雅地处理 SSL 验证。如果 SSL
握手不成功,JGit 会询问 CredentialsProvider是否应跳过 SSL 验证。
在这个过程中,CredentialsProvider得到一个 InformationalMessage以文字方式描述问题,最多三个 YesNoType CredentialItem s 决定是否跳过此操作、当前存储库和/或始终的 SSL 验证。
似乎更改是在考虑交互式 UI 的情况下进行的,可能很难以编程方式回答这些“凭据请求”。 commit message of this change更详细地描述行为。
如果您确定 SSL 验证是唯一的 InformationalMessage将发送,您可以应用 this test 中使用的技术伴随着变化而盲目地对所有这些问题回答"is"。
对于早期版本的 JGit,或者如果 CredentialsProvider模型不符合您的需求,下面介绍了两种解决方法。

要解决此限制,您可以 手动执行特定的克隆步骤 正如以下评论中所建议的:

  • 使用 InitCommand
  • 初始化存储库
  • 将 ssl 验证设置为 false

  •     StoredConfig config = git.getRepository().getConfig();
        config.setBoolean( "http", null, "sslVerify", false );
        config.save();
    
  • 获取(参见 FetchCommand)
  • 结帐(请参阅结帐命令)

  • 解决此问题的另一种方法是 提供 HttpConnectionFactory 返回 HttpConnection s 带有虚拟主机名和证书验证器。例如:
    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 代码支持),但您可以自由使用自己的实现或由 org.eclipse.jgit.transport.http.apache 提供的实现。使用 Apache http 组件的包。
    当前使用的连接工厂可以通过 HttpTransport::setConnectionFactory() 更改:
    HttpConnectionFactory preservedConnectionFactory = HttpTransport.getConnectionFactory();
    HttpTransport.setConnectionFactory( new InsecureHttpConnectionFactory() );
    // clone repository
    HttpTransport.setConnectionFactory( preservedConnectionFactory );
    
    不幸的是,连接工厂是一个单例,因此当 JGit 命令并发执行时,这个技巧需要额外的工作(例如,一个线程局部变量来控制 sslVerify 是打开还是关闭)。

    关于jgit - 为 JGit 克隆命令关闭 SSL 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33998477/

    相关文章:

    java - 如何使用 maven jgit 构建号插件打印构建时间戳和构建号?

    java - 使用 JGit 获取存储库中的最新提交

    eclipse - egit merge 模式是什么意思?

    java - 使用 jgit 递归检查 Git 工作副本中的更改的最快方法是什么?

    git - JGit 列出远程标签并按创建日期排序

    java - 使用 jgit : Remote does not have <branchname> available for fetch 获取 Git 失败

    java - JGit推送不更新文件

    java - 将jgit添加为gradle依赖项可防止我的主类成为加载器

    java - "Access Denied"尝试复制使用 JGit 拉取的文件时出现消息

    github - Spring Cloud/Jgit/Github无法使用SSH