libgit2sharp icon indicating copy to clipboard operation
libgit2sharp copied to clipboard

'Too many redirects or authentication replays' on clone from TFS

Open MustafaJamal opened this issue 6 years ago • 28 comments

After updating to Team Foundation Server TFS 2018 & 2017 Update 3, we are not be able to login to GIT repository using LibGit2Sharp library using Access Token. Please check the code below:

    `
    string accessToken = "eyJ0eXAiOiJKV1QiLCJ...";
    NetworkCredential gitCredentials = new NetworkCredential(string.Empty, accessToken);
    string localRepoPath = string.Empty;
    string gitTfsRepo = "http://mjtfs2017:8080/tfs/DefaultCollection/_git/GITTest001";

    try
    {
        localRepoPath = Repository.Clone(gitTfsRepo, @"D:\temp\GIT",
            new CloneOptions()
            {
                CredentialsProvider = GetCredentialsHandler(gitCredentials),
                IsBare = false
            });

    }
    catch (Exception err)
    {
        Console.WriteLine(err);
    }

    Console.WriteLine(localRepoPath);
    `

I communicated with Microsoft TFS/VSTS Team they gave following response:

The fact that you received those responses from the code snip I provided means that your extension is correctly configured (regarding scopes at least) and TFS is correctly accepting the extension’s access token to perform git operations through HTTP, when the git client sends it.

Additionally, if I use the next command, using git for Windows, I’m able to fully interact with a TFS repo with that access token:

git -c http.extraheader="Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJ..." clone http://at1-tfs-test1-angallo.westus2.cloudapp.azure.com:8080/tfs/DefaultCollection/_git/test_project_1

But that same command doesn’t work for git for Linux, probably because my git client on my Linux machine doesn’t send or correctly consider these HTTP headers (just as LibGit2Sharp seems to not do too (from your latest Fiddler trace I still see the Authentication header missing)). So I still believe the problem here comes from the git client, not TFS or the access token.

Please suggest, thanks in advance.

LibGit2Sharp version: 0.26.0-preview-0027

MustafaJamal avatar Jul 16 '18 07:07 MustafaJamal

After updating to Team Foundation Server TFS 2018 & 2017 Update 3, we are not be able to login to GIT repository using LibGit2Sharp library using Access Token

Did this work before?

Have you tried creating a Personal Access Token instead of a bearer auth token?

ethomson avatar Jul 16 '18 07:07 ethomson

(Please also be sure to delete that access token, now that it’s been posted publicly.)

ethomson avatar Jul 16 '18 07:07 ethomson

Did this work before?

No it never worked

Have you tried creating a Personal Access Token instead of a bearer auth token?

Yes I tried PAT on TFS 2018 and same exception is occurring.

MustafaJamal avatar Jul 16 '18 08:07 MustafaJamal

I use PATs on TFS 2018 and VSTS with no problem. Can you show me some code or a fiddler or wireshark trace?

ethomson avatar Jul 16 '18 08:07 ethomson

Here is the code:

    `static void Main(string[] args)
    {
        NetworkCredential networkCredential = new NetworkCredential(string.Empty,
            "ssormigjrmdsm7...");
        string localRepoPath = Repository.Clone("http://mr4tfs:8080/tfs/DefaultCollection/_git/GIT001", @"D:\temp\GIT",
            new CloneOptions()
            {
                CredentialsProvider = GetCredentialsHandler(networkCredential),
                IsBare = false
            });
    }

    internal static CredentialsHandler GetCredentialsHandler(NetworkCredential gitCredentials)
    {
        CredentialsHandler credHandler = (url, fromUrl, types) =>
        {
            if ((types & SupportedCredentialTypes.UsernamePassword) == SupportedCredentialTypes.UsernamePassword)
            {
                UsernamePasswordCredentials usernamePasswordCredentials = new UsernamePasswordCredentials();
                if (string.IsNullOrEmpty(gitCredentials.Domain) && string.IsNullOrEmpty(gitCredentials.UserName))
                {
                    usernamePasswordCredentials.Username = gitCredentials.Password;
                }
                else
                {
                    if (string.IsNullOrEmpty(gitCredentials.Domain))
                    {
                        usernamePasswordCredentials.Username = gitCredentials.UserName;
                    }
                    else
                    {
                        usernamePasswordCredentials.Username = string.Format("{0}\\{1}", gitCredentials.Domain,
                            gitCredentials.UserName);
                    }
                }

                usernamePasswordCredentials.Password = gitCredentials.Password;

                return usernamePasswordCredentials;
            }

            return new DefaultCredentials();
        };

        return credHandler;
    }`

Fiddler trace:

TFS2018_GIT_AUTH_ERR.zip

MustafaJamal avatar Jul 16 '18 11:07 MustafaJamal

@ethomson waiting for your response.

MustafaJamal avatar Jul 19 '18 08:07 MustafaJamal

Hi @ethomson

Using the blow code i am able to download the complete Repo (GitLab)

_gitrepo = https://repo.mycompany.com/GPP/baseproject.git

But i need to download/clone only selected folder from master branch, is that possible? (I am getting same error - Too many redirects or authentication replays) _gitrepo = https://repo.mycompany.com/GPP/baseproject/tree/master/src/myLibCode

Code Snippet: private static void DownloadGitRepo(string _gitrepo, string _pathtodownload) { var secrets = new SecretStore("git"); var auth = new BasicAuthentication(secrets); var creds = auth.GetCredentials(new TargetUri("https://repo.mycompany.com"));

        var options = new CloneOptions
        {
            CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials
            {
                Username = creds.Username,
                Password = creds.Password
            },
        };

        Repository.Clone(_gitrepo, _pathtodownload, options);
    }

satyaprakashv avatar Jul 23 '18 14:07 satyaprakashv

@satyaprakashv check the answer of your question here: https://stackoverflow.com/questions/46806069/clone-selected-folders-from-repo

MustafaJamal avatar Jul 24 '18 08:07 MustafaJamal

@MustafaJamal , Thanks, It is very helpful..

satyaprakashv avatar Jul 24 '18 08:07 satyaprakashv

@MustafaJamal I was digging with this issue all the morning and this is a simple workaround if found with TFS 2018 Update 2 :

LibGit2Sharp.Repository.Clone($"https://usercouldbeanything:{personalaccesstoken}@yourtfsserver/tfs/CollectionName/ProjectName/_git/GitRepoName", "GitRepoName");

If I use the basic auth UsernamePasswordCredentials with the same parameters :

LibGit2Sharp.Repository.Clone("https://yourtfsserver/tfs/CollectionName/ProjectName/_git/GitRepoName", "GitRepoName", new CloneOptions()
{
  CredentialsProvider = (_url, _user, _cred) =>
  {
    return new UsernamePasswordCredentials { Username = "usercouldbeanything", Password = personalaccesstoken };
  }
 });

I'm getting this exception :

LibGit2Sharp.LibGit2SharpException: 'too many redirects or authentication replays'

@ethomson can it be a bug with the librairy?

rachkoud avatar Jul 24 '18 11:07 rachkoud

@ethomson waiting for your reply. Any update on this ?

MustafaJamal avatar Aug 28 '18 11:08 MustafaJamal

Had the same issue here. Turned out that if a wrong password was send once, the user account got locked. Normally in out IT we can enter the password three times, wrongly. I dont think the credentials are send multiple times during Clone? Info: No TFS server, got here via the Issue https://github.com/libgit2/libgit2sharp/issues/1168, which was closed in favor of this issue.

BenjaminEhlert avatar Oct 02 '18 13:10 BenjaminEhlert

@ethomson we are waiting for response

MustafaJamal avatar Apr 02 '19 11:04 MustafaJamal

I'm getting this on push using the github_actions bot token, which acts a bit weirdly because it's an integration. Any suggestions for that? I've tried a combination of

  • Cloning with https://[email protected].
  • Cloning with https://token:[email protected].
  • Pushing with token in Username and empty password.
  • Pushing with token in Useranme and x-oauth-basic as the password.

Using a regular PAT with a real username works as credentials, just fails for the github_actions token it seems.

Cyberboss avatar Sep 18 '20 01:09 Cyberboss

NuKeeper switched from version 0.26.2 to 0.27.0-preview-0034 and now I'm getting this error when trying to clone a repository from an Azure Devops Server 2019 instance.

Reverting to 0.26.2 fixes the isssue.

See https://github.com/NuKeeperDotNet/NuKeeper/issues/1042

I will try to investigate the network traffic using wireshark next week.

CrispyDrone avatar Oct 10 '20 21:10 CrispyDrone

@rachkoud thank you for the this hint:

LibGit2Sharp.Repository.Clone($"https://usercouldbeanything:{personalaccesstoken}@yourtfsserver/tfs/CollectionName/ProjectName/_git/GitRepoName", "GitRepoName");

the code runs through without any exception but unfortunately if I then go to the local folder, I find it contains the items from the origin, but a git pull, git fetch or git push results authentication error. Interestingly the error message points to the proper address like _https://yourtfsserver/tfs/CollectionName/ProjectName/git/GitRepoName. The remote.origin.url entry displayed by git config --list however displays the one in the code snippet above. Pushing changes programmatically using LibGit2Sharp works.

klapantius avatar Feb 03 '21 15:02 klapantius

NuKeeper switched from version 0.26.2 to 0.27.0-preview-0034 and now I'm getting this error when trying to clone a repository from an Azure Devops Server 2019 instance.

Reverting to 0.26.2 fixes the isssue.

See NuKeeperDotNet/NuKeeper#1042

I will try to investigate the network traffic using wireshark next week.

I found the same issue. Reverting to 0.26.2 allowed me to checkout also.

curea avatar May 27 '21 03:05 curea

Ran into similar issues when trying to clone from an on premise Azure Devops Server 2020 into a docker container.

We were able to get it working by doing the following while having Basic Authentication disabled.

var token = "myPatToken";
var byteArray = Encoding.ASCII.GetBytes(":" + myPatToken);
var encodedToken = Convert.ToBase64String(byteArray);

var options = new CloneOptions
{
    FetchOptions = new FetchOptions
    {
        CustomHeaders = new[]
        {
            $"Authorization: Basic {encodedToken}"
        }
    }
};

return Repository.Clone("https://...", ".", options);

sfwester avatar Nov 23 '21 21:11 sfwester

We use UsernamePasswordCredentials and get the same error message recently. The same code, the cloning with UsernamePasswordCredentials worked before for months and now not anymore.

Any hints? Did change something in the API?

PatrickGrub avatar Nov 26 '21 15:11 PatrickGrub

We use UsernamePasswordCredentials and get the same error message recently. The same code, the cloning with UsernamePasswordCredentials worked before for months and now not anymore.

Any hints? Did change something in the API?

Facing the same issue.

Sherry112 avatar Jan 04 '22 10:01 Sherry112

At cognigy we are also facing this issue. It has been working for the last months without issues and started to break for us at the 12. of January. Any ideas of what we can change in order to fix this?

mayrbenjamin92 avatar Jan 16 '22 12:01 mayrbenjamin92

Hi guys! This response might be surprising, but: We could actually fix this! In my case, our PAT (=Personal access token) was expired! I just had to create a new token and cloning worked, again! Wanted to share this as I was also searching for solutions for quite some time! The error message is just a bit misleading...

@Sherry112, @PatrickGrub :)

mayrbenjamin92 avatar Jan 18 '22 19:01 mayrbenjamin92

Ran into similar issues when trying to clone from an on premise Azure Devops Server 2020 into a docker container.

We were able to get it working by doing the following while having Basic Authentication disabled.

var token = "myPatToken";
var byteArray = Encoding.ASCII.GetBytes(":" + myPatToken);
var encodedToken = Convert.ToBase64String(byteArray);

var options = new CloneOptions
{
    FetchOptions = new FetchOptions
    {
        CustomHeaders = new[]
        {
            $"Authorization: Basic {encodedToken}"
        }
    }
};

return Repository.Clone("https://...", ".", options);

Do you think, we could use a similar approach with Repository.Network.Push() ? (ie with Custom Headers)

manojbaishya avatar Feb 15 '22 10:02 manojbaishya

If it's helpful, I am able to Clone, Pull, Push, everything in an AzureDevOps git repository with a personal access token (PAT) with Code (Read, Write, and Manage) permissions -- just supply the PAT as password for the username, empty string password in a UsernamePasswordCredentials object, and give that in the Credential Handler

# credential provider:
public static CredentialsHandler GetDefaultCredentialsHandler(string projectName)
     => (_url, _user, _cred) => new UsernamePasswordCredentials
    {
        Username = personalAccessToken;
        Password = string.Empty
    };

# clone method:
var cloneOptions = new CloneOptions
{
    CredentialsProvider = GetDefaultCredentialsHandler(this.ProjectName),
};

Repository.Clone(sourceURL, localClonePath, cloneOptions);

zsd4yr avatar Sep 10 '22 02:09 zsd4yr

Did anyone get this to work with Github and personal access tokens? Because I don't seem to get this done...

SeppPenner avatar Nov 14 '23 17:11 SeppPenner

Here's the credentials handler I use today. Seems to work fine: https://github.com/tgstation/tgstation-server/blob/ac290fc6ffce19c41233bb3a8321e984d9c1e722/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs#L83-L108

User/pass is user/token

Cyberboss avatar Nov 14 '23 17:11 Cyberboss

Here's the credentials handler I use today. Seems to work fine: https://github.com/tgstation/tgstation-server/blob/ac290fc6ffce19c41233bb3a8321e984d9c1e722/src/Tgstation.Server.Host/Components/Repository/LibGit2RepositoryFactory.cs#L83-L108

User/pass is user/token

Mhm, strange. I did it the same way. Maybe the token is corrupt...

SeppPenner avatar Nov 14 '23 17:11 SeppPenner