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();
}