【问题标题】:LibGit2Sharp and Authentication UILibGit2Sharp 和身份验证 UI
【发布时间】:2018-04-24 21:27:04
【问题描述】:

我正在使用 LibGit2Sharp 向应用程序添加许多 Git 操作。我添加了Microsoft.Alm.Authentication 以帮助进行身份验证和凭据管理器访问。它非常适合检索已从命令行输入的凭据。

但是,还有什么方法可以连接到凭据管理器的登录 UI,该 UI 会提示输入 Github、BitBucket 和 VSTS 的用户名和密码。此 UI 从命令行自动弹出,但在使用 LibGit2Sharp 时不会触发。

我查看了 Github 上的 GitCredentialManager 项目,我可以看到提供 UI 的组件,但在尝试弄清楚如何明确挂钩之前,我是否缺少某种方式,这是提供的Microsoft.Alm.Authentication(或相关包)的一部分?或者任何人都可以指出如何最好地连接它的示例或指导?

【问题讨论】:

    标签: c# authentication libgit2sharp credential-manager


    【解决方案1】:

    我设法让您的解决方案进行了一些小的修改。我在此处粘贴示例代码以使用 git 凭据进行推送。它使用已存储在计算机中的凭据工作,并在第一次使用 UI 时提示输入凭据。

    到目前为止,我遇到的唯一问题是当用户提示输入凭据并且他们输入了无效的用户/密码时。 Git 写入控制台询问用户/通行证,直到您输入该过程才完成。试图监控 StandardError/Output 没有成功。我在 stderror 中得到错误文本,但只有在手动填写之后。

    public void PushLibGit2Sharp(string repositoryFolder, string branch)
    {
        using (var repo = new Repository(repositoryFolder))
        {
            var options = new PushOptions
            {
                CredentialsProvider = (url, usernameFromUrl, types) =>
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo
                    {
                        FileName = "git.exe",
                        Arguments = "credential fill",
                        UseShellExecute = false,
                        WindowStyle = ProcessWindowStyle.Hidden,
                        CreateNoWindow = true,
                        RedirectStandardInput = true,
                        RedirectStandardOutput = true,
                        RedirectStandardError = true
                    };
    
                    Process process = new Process
                    {
                        StartInfo = startInfo
                    };
    
                    process.Start();
    
                    // Write query to stdin. 
                    // For stdin to work we need to send \n instead of WriteLine
                    // We need to send empty line at the end
                    var uri = new Uri(url);
                    process.StandardInput.NewLine = "\n";       
                    process.StandardInput.WriteLine($"protocol={uri.Scheme}");
                    process.StandardInput.WriteLine($"host={uri.Host}");
                    process.StandardInput.WriteLine($"path={uri.AbsolutePath}");
                    process.StandardInput.WriteLine();
    
                    // Get user/pass from stdout
                    string username = null;
                    string password = null;
                    string line;
                    while ((line = process.StandardOutput.ReadLine()) != null)
                    {
                        string[] details = line.Split('=');
                        if (details[0] == "username")
                        {
                            username = details[1];
                        }
                        else if (details[0] == "password")
                        {
                            password = details[1];
                        }
                    }
    
                    return new UsernamePasswordCredentials()
                    {
                        Username = username,
                        Password = password
                    };
                }
            };
    
            repo.Network.Push(repo.Branches[branch], options);
        }
    }
    

    【讨论】:

      【解决方案2】:

      不幸的是,libgit2(或 LibGit2Sharp)中没有直接与 git-credential-helper 功能对话的功能,这是 git 本身用来执行此操作的功能。

      相反,您可以在PushOptions(或FetchOptions)上设置CredentialsHandler,例如:

      options.CredentialsProvider = (url, usernameFromUrl, types) => {
          string username, password;
      
          Uri uri = new Uri(url);   
          string hostname = uri.Host;
      
          ProcessStartInfo startInfo = new ProcessStartInfo();
          startInfo.UseShellExecute = false;
      
          startInfo.RedirectStandardInput = true;
          startInfo.RedirectStandardOutput = true;
          startInfo.RedirectStandardError = true;
      
          startInfo.FileName = "git.exe";
          startInfo.Arguments = "credential fill";
      
          Process process = new Process();
          process.StartInfo = startInfo;
          process.Start();
      
          process.StandardInput.WriteLine("hostname={0}", hostname);
          process.StandardInput.WriteLine("username={0}", usernameFromUrl);
      
          while ((line = process.StandardOutput.ReadLine()) != null)
          {
              string[] details = line.Split('=', 2);
              if (details[0] == "username")
              {
                  username = details[1];
              }
              else if (details[0] == "password")
              {
                  password = details[1];
              }
          }
      
          return new UsernamePasswordCredentials(username, password);
      };
      

      【讨论】:

      • 注意,这是未经测试的,但我认为充分表达了这些想法。请随时指出问题或直接进行修改。
      • 这可能会奏效——不过我采用了另一种方法——我最终没有使用 LibGit2Sharp 进行远程操作,而是使用 Process 转至命令行,确实会调出身份验证对话框。但这很糟糕,因为这会强制依赖 Git 并安装并启用凭据管理器(至少现在是 Windows 上的默认设置)。
      猜你喜欢
      • 2018-04-21
      • 2021-05-19
      • 1970-01-01
      • 2021-07-20
      • 2015-02-02
      • 2018-02-24
      • 1970-01-01
      • 2015-08-10
      • 2012-10-14
      相关资源
      最近更新 更多