Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Authentication not supported": jgit error when trying to clone tfs hosted git repo

When I try to clone a tfs hosted git repo http://tfstta.com:8080/tfs/DefaultCollection/_git/SampleTFSGit from my linux machine, I face the Authentication not supported error:

org.eclipse.jgit.api.errors.TransportException: http://:@tfstta.int.thomson.com:8080/tfs/DefaultCollection/_git/SampleTFSGit.git: authentication not supported*

Enabling basic authentication/alternate credentials does not seem to be an option.

Could someone please tell me a work around for this? I would be very grateful!

like image 568
pavithra raghavan Avatar asked Dec 25 '22 03:12

pavithra raghavan


2 Answers

Goto Eclipse Menu

Window -> Preferences -> Team -> Git -> right side panel update time to 3000. `Connection timeout (seconds): 3000. Click on Apply and Close button. Clone again it will solve your problem.

like image 133
UdayKiran Pulipati Avatar answered Dec 28 '22 06:12

UdayKiran Pulipati


This issue happens because JGit doesn't fully support NTLM, and instead of falling back to Basic auth or something else, it will stop right there.

Usually TFS answers failed authentication with multiple WWW-Authenticate headers. What happens here is that there is a bug in JGit's org.eclipse.jgit.transport.http.apache.HttpClientConnection, that will take into consideration only the last of the WWW-Authenticate headers, making it give up before even trying other connection types.

What I suggest is use your own implementation of org.eclipse.jgit.transport.http.HttpConnection, implementing like this:

@Override
public Map<String, List<String>> getHeaderFields() {
    Map<String, List<String>> ret = new HashMap<>();
    for (Header hdr : resp.getAllHeaders()) {
        List<String> list;
        if(ret.containsKey(hdr.getName())) list = ret.get(hdr.getName());
        else { list = new LinkedList<>(); ret.put(hdr.getName(), list); }
        for (HeaderElement hdrElem : hdr.getElements())
            list.add(hdrElem.toString());
    }
    return ret;
}

Or if you are lazy (like me), you can just switch to org.eclipse.jgit.transport.http.JDKHttpConnection and be happy because it uses native Java connection underneath, that works correctly.

If you are trying to use Spring Cloud Config Server with a TFS Git Repository, my choice is just to implement your own ConfigurableHttpConnectionFactory

/**
 * This will use native Java connections, instead of crappy ecplise implementation.
 * There will be no management of implementation though. I cannot assure
 */
public class SpringJDKConnectionFactory extends JDKHttpConnectionFactory implements ConfigurableHttpConnectionFactory {
    @Override
    public void addConfiguration(MultipleJGitEnvironmentProperties environmentProperties) {
    }
}

And have a configuration loading over the Spring's default:

@Configuration
public class JGitConnectionFactoryConfiguration {
    @Bean
    @Primary
    public ConfigurableHttpConnectionFactory configurableHttpConnectionFactory() {
        return new SpringJDKConnectionFactory();
    }
}

But beware, TFS will probably not like Basic auth with direct passwords. So create a "Personal Access Token" in TFS, and use that as a password instead.

Simple sample code:

public static void main(String[] args) throws GitAPIException, IOException {
    CloneCommand cmd;
    String url = "http://tfs-url.com/Git-Repo";
    File file = new File("build/git_test");
    if(file.exists())
        FileUtils.delete(file,FileUtils.RECURSIVE);
    cmd = new CloneCommand();
    cmd.setDirectory(file);
    cmd.setURI(url);
    //#use Personal access tokens as basic auth only accepts these
    cmd.setCredentialsProvider(new UsernamePasswordCredentialsProvider("UserAccount","personalaccesstoken"));
    ConfigurableHttpConnectionFactory cf = new SpringJDKConnectionFactory();
    HttpTransport.setConnectionFactory(cf);
    Git git = cmd.call();
}
like image 31
gabriel Avatar answered Dec 28 '22 07:12

gabriel