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

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!

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.

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

You might want to try https://www.visualstudio.com/en-us/products/team-explorer-everywhere-vs.aspx since it is Microsoft's cross-platform TFS command-line. The code is posted on GitHub if you want to try and patch the authentication helpers back to jGit.

I would recommend you to upgrade your TFS server to the latest Update 3 and then use SSH Authentication for Git Repository.
SSH Support for Git Repos
With TFS 2015 Update 3, you can now connect to any Team Foundation
Server Git repo using an SSH key. This is very helpful if you develop
on Linux or Mac. Just upload your personal SSH key and you're ready to
go.

I have faced this issue with a new pc (configured by someone else). Fixed error with reinstalling JDK and running eclipse with it.

I used a bad approach but for initial work, it's fine for me.
In my case, I switched Project visibility on gitlab from private to public. Go to Gitab -> <your project> -> Settings -> General -> Visibility, project features, permissions -> switch to Public
In application.properties I added only spring.cloud.config.server.git.uri without authentication properties and also at the end of the gitlab uri added .git
http://gitlab.com/<your-repo-name>.git
I don't recommend this approach for people who work tasks for the company.

When you use command below, you'll be prompted to enter the username and password.
git-clone http://:#tfstta.int.thomson.com:8080/tfs/DefaultCollection/_git/SampleTFSGit
In my test, when send the command, you'll be prompted a Windows Security. It's not needed to use basic authentication/alternate credentials, simply type domaine\username and the password will connect to TFS.

Related

how to connect to document content server or repository using opencmis

I tried to connect to Documentum content server repository using cmis API, but I am not able to connect.
I have Documentum content server & web top application, Now I just want to connect to repository, and I need repository session.
How to connect to documentum repository using CMIS API?
I tried to use following code, but its not working because Its a code snipet which I used for connecting Alfresco repository, and I just modified same with Documentum server IP.
So any sample code will be really helpful, At list If I can get repository session object, It would be great.
SessionFactory factory = SessionFactoryImpl.newInstance();
Map<String, String> parameter = new HashMap<String, String>();
// user credentials
parameter.put(SessionParameter.USER, "user");
parameter.put(SessionParameter.PASSWORD, "pass");
// Uncomment for Atom Pub binding
parameter.put(SessionParameter.ATOMPUB_URL, "http://localhost:8080//cmis/atom");
// Uncomment for Atom Pub binding
parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
parameter.put(SessionParameter.AUTHENTICATION_PROVIDER_CLASS,
CmisBindingFactory.NTLM_AUTHENTICATION_PROVIDER);
List<Repository> repositories = factory.getRepositories(parameter);
sourceSession = repositories.get(0).createSession();
With above code I am not able to get repository session, so please let me know if I am doing anything wrong, or please share any other sample code if you have.
I used above code to get Alfresco repository session, But I am not familiar with documentum, So I tried with modifying same alfresco cmis code.
First of all, avoid NTLM! Even if you get it working at some point, you will run into strange issues later.
This document is a bit outdated, but maybe it contains a few clues for you: http://www.jouvinio.net/wiki/images/a/a4/Documentum_cmis_6.7_deployment.pdf

'Address already in use' when running tests using Spring LDAP embedded server

I am trying to use Spring LDAP in one of my Spring Boot projects but I am getting an 'Address already in use' error when running multiple tests.
I have cloned locally the sample project here:
https://spring.io/guides/gs/authenticating-ldap/
...and just added the boilerplate test normally created by Spring Boot to verify that the Application Context loads correctly:
#RunWith(SpringRunner.class)
#SpringBootTest
public class MyApplicationTests {
#Test
public void contextLoads() {
}
}
If run alone, this test passes. As soon as LdapAuthenticationTests and MyApplicationTests are run together, I get the error above for the latter.
After debugging a bit, I've found out that this happens because the system tries to spawn a second instance of the embedded server.
I am sure I am missing something very stupid in the configuration.
How can I fix this problem?
I had a similar problem, and it looks like you had a static port configured (as was in my case).
According to this article:
Spring Boot starts an embedded LDAP server for each application
context. Logically, that means, it starts an embedded LDAP server for
each test class. Practically, this is not always true since Spring
Boot caches and reuses application contexts. However, you should
always expect that there is more than one LDAP server running while
executing your tests. For this reason, you may not declare a port for
your LDAP server. In this way, it will automatically uses a free port.
Otherwise, your tests will fail with “Address already in use”
Thus it might be a better idea not to define spring.ldap.embedded.port at all.
I addressed the same issue. I solved it with an additional TestExecutionListener since you can get the InMemoryDirectoryServer bean.
/**
* #author slemoine
*/
public class LdapExecutionListener implements TestExecutionListener {
#Override
public void afterTestClass(TestContext testContext) {
InMemoryDirectoryServer ldapServer = testContext.getApplicationContext().getBean(InMemoryDirectoryServer.class);
ldapServer.shutDown(true);
}
}
And on each SpringBootTest (or only once in an abstract super class)
#RunWith(SpringRunner.class)
#SpringBootTest
#TestExecutionListeners(listeners = LdapExecutionListener.class,
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
public class MyTestClass {
...
}
also do not forget
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
to avoid disabling the whole #SpringBootTest auto configuration.
Okay, I think I found a solution by adding a #DirtiesContext annotation to my test classes:
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
If you are using spring embedded ldap, try to comment or remove port value from config file as below :
spring :
ldap:
embedded:
base-dn: dc=example,dc=org
credential:
username: cn=admin,dc=example,dc=org
password: admin
ldif: classpath:test-schema.ldif
# port: 12345
validation:
enabled: false
Try specifying the web environment type and the base configuration class (the one with !SpringBootApplication on it).
#RunWith(SpringRunner.class)
#SpringBootTest(
classes = MyApplication.class,
webEnvironment = RANDOM_PORT
)
public class MyApplicationTests {
#Test
public void contextLoads() {
}
}
Do this for all your test classes.
I solved this problem by adding #DirtiesContext over each test class that requires embedded ldap server. In my case (and as I feel in many others), embedded ldap server was starting up at every #SpringBootTest, since I added all spring.ldap.embedded.* properties to general application-test.properties. Therefore, when I run a bunch of tests, the problem of 'Address already in use' broke all test passing.
Steps I followed:
create an additional test profile (with corresponding named application properties file, e.g. 'application-ldaptest.properties')
move to that file all spring.ldap.embedded.* properties (with fixed port value)
over all #SpringBootTest-s that do require embedded server running up, add #ActiveProfiles("testladp") and #DirtiesContext annotations.
Hope, that helps.

connection refused by server error when codenameone project is copied to another machine

I have a very strange problem:
I have created a project in Intellij using the Codename One plugin.
In this project I access a Google Sheet using Oauth2 authentication
following these directions from the Codename One site.
https://www.codenameone.com/google-login.html
My code to do this works fine on my computer (Windows 10).
If I copy that code to another computer (Windows 10 or OS X) and try to access the Google Sheet, I get a "Connection refused by server" error.
Specifically, I get the error after I click on the "Allow" button in
the Google Login dialog box.
I have tried this on several computers.
I receive the error no matter what network/ISP I am using when I try to access the Google Sheet.
The stack trace relating to the error looks like this:
java.lang.Throwable: Connection refused by server
at javafx.scene.web.WebEngine$LoadWorker.describeError(WebEngine.java:1461)
at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1400)
at javafx.scene.web.WebEngine$LoadWorker.access$1200(WebEngine.java:1278)
at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1265)
at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2443)
at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2287)
at com.sun.webkit.network.URLLoader.twkDidFail(Native Method)
at com.sun.webkit.network.URLLoader.notifyDidFail(URLLoader.java:883)
at com.sun.webkit.network.URLLoader.lambda$didFail$102(URLLoader.java:866)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Process finished with exit code 0
The code that is being executed when the error is generated is:
public void oauth2GoogleLogin()
{
String clientId = "xxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com";
String redirectURI = "http://localhost:8080";
String clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxx";
Login gc = GoogleConnect.getInstance();
gc.setClientId(clientId);
gc.setRedirectURI(redirectURI);
gc.setClientSecret(clientSecret);
gc.setScope("https://www.googleapis.com/auth/spreadsheets");
gc.setCallback(new LoginCallback() {
#Override
public void loginFailed(String errorMessage) {
super.loginFailed(errorMessage);
}
#Override
public void loginSuccessful() {
super.loginSuccessful();
System.out.println("Logged in.");
token = gc.getAccessToken().getToken();
//saveData();
}
});
if(!gc.isUserLoggedIn()){
gc.doLogin();
}else{
....some code to do stuff...
}
}
As I have said, this code works fine on the computer where I wrote it, but if I transfer the Intellij/Codename One project to another computer, it no longer works.
It seems to me that the problem is probably in the callback, and that the server that is refusing the connection is probably my own computer being accessed via the http://localhost:8080. But I'm not sure. Can anyone enlighten me?
If both machines no longer work that makes more sense that a regression in newer versions of JavaFX's web browser broke the Google OAuth2 process.
Unfortunately, that's a huge problem. We can't fix JavaFX and if they push out a broken update we are stuck.
A workaround might be to try an older version of the VM e.g. 1.8.67 or something.

How to debug NServiceBus ServiceControl instance

I've installed the ServiceControl Management Utility and I'm trying to add an instance.
I would like to run the instance under a service account because we use SQLServer transport but pmthe installation page I get the error "Invalid password".
The account is hosting another windows service on the same machine.
I've tried other admin accounts and creating the instance through the UI and Powershell scripts.
I'm 200% sure the password is correct.
Is there anyway I can increase the logging to determine what is failing?
Strangely, I can change the service account under the initial install and it works.. I was eventually able to get the service running using an SQL login but I would prefered to use integrated security and not keep the username and password in the connection string.
A patch that addresses this bug has been released. See - https://github.com/Particular/ServiceControl/releases/tag/1.7.3. Thanks Kye for making us aware of the issue
This is code that does the validation.
public bool CheckPassword(string password)
{
if (Domain.Equals("NT AUTHORITY", StringComparison.OrdinalIgnoreCase))
{
return true;
}
var localAccount = Domain.Equals(Environment.MachineName, StringComparison.OrdinalIgnoreCase);
var context = localAccount ? new PrincipalContext(ContextType.Machine) : new PrincipalContext(ContextType.Domain);
return context.ValidateCredentials(QualifiedName, password);
}
So in a multi-domain environment it might run into trouble.
Raise a bug here and we will be able to give you a better response.

How do I get FiddlerCore programmatic Certificate Installation to 'stick'?

I'm using FiddlerCore to capture HTTP requests. Everything is working including SSL Captures as long as the Fiddler certificate is manually installed. I've been using manual installation through Fiddler's Options menu and that works fine.
However, if I use the FiddlerCore provided CertMaker class static methods to add the Fiddler certificate I find that I can use the certificate added to the cert root only in the current session. As soon as I shut down the application and start back up, CertMaker.rootCertExists() returns false.
I use the following code to install the certificate for the current user (from an explicit menu option at this point):
public static bool InstallCertificate()
{
if (!CertMaker.rootCertExists())
{
if (!CertMaker.createRootCert())
return false;
if (!CertMaker.trustRootCert())
return false;
}
return true;
}
The cert gets installed and I see it in the root cert store for the current user. If I capture SSL requests in the currently running application it works fine.
However, if I shut down the running exe, restart and call CertMaker.certRootExists() it returns false and if I try to capture SSL requests the SSL connection fails in the browser. If I recreate the cert and then re-run the requests in the browser while the app stays running it works again. I now end up with two certificates in the root store.
After exiting and relaunching certMaker.certRootExists() again returns false. Only way to get it to work is to register the cert - per exe session.
What am I doing wrong to cause the installation to not stick between execution of the same application?
I was able to solve this problem and create persistent certificates that are usable across EXE sessions, by removing the default CertMaker.dll and BcMakeCert.dll assemblies that FiddlerCore installs and using and distributing the makecert.exe executable instead.
makecert.exe appears to create certificates in such a way that they are usable across multiple runs of the an application, where the included assemblies are valid only for the current application's running session.
Update:
If you want to use the CertMaker.dll and BcMakeCert.dll that FiddlerCore installs by default, you have to effectively cache and set the certificate and private key, using Fiddlers internal preferences object. There are a couple of keys that hold the certificate after it's been created and you need to capture these values, and write them into some sort of configuration storage.
In the following example I have a static configuration object that holds the certificate and key (persisted to a config file when the app shuts down):
public static bool InstallCertificate()
{
if (!CertMaker.rootCertExists())
{
if (!CertMaker.createRootCert())
return false;
if (!CertMaker.trustRootCert())
return false;
// persist Fiddlers certificate into app specific config
App.Configuration.UrlCapture.Cert =
FiddlerApplication.Prefs.GetStringPref("fiddler.certmaker.bc.cert", null);
App.Configuration.UrlCapture.Key =
FiddlerApplication.Prefs.GetStringPref("fiddler.certmaker.bc.key", null);
}
return true;
}
public static bool UninstallCertificate()
{
if (CertMaker.rootCertExists())
{
if (!CertMaker.removeFiddlerGeneratedCerts(true))
return false;
}
// persist Fiddlers certificate into app specific config
App.Configuration.UrlCapture.Cert = null;
App.Configuration.UrlCapture.Key = null;
return true;
}
After installing a certificate this code captures the certificate and private key into the configuration object which persists that value later. For uninstallation, the values are cleared.
At the beginning of the application or the beginning of the capture process, prior to calling CertMaker.rootCertExists() the keys are set from the configuration values. I do this at the beginning of my capture form:
public FiddlerCapture()
{
InitializeComponent();
// read previously saved Fiddler certificate from app specific config
if (!string.IsNullOrEmpty(App.Configuration.UrlCapture.Cert))
{
FiddlerApplication.Prefs.SetStringPref("fiddler.certmaker.bc.key",
App.Configuration.UrlCapture.Key);
FiddlerApplication.Prefs.SetStringPref("fiddler.certmaker.bc.cert",
App.Configuration.UrlCapture.Cert);
}
}
Using this mechanism for saving and then setting the capture settings makes the certificates persist across multiple EXE sessions when using CertMaker.dll.
More detailed info is available this detailed blog post on FiddlerCore.
If anyone is still interested, I found an easier solution based on the demo that Fiddler provides. This demo simply calls CertMaker.trustRootCert(), and strangely enough, it sticks! The first time it will ask whether you want to install the certificate, but after that, the function just returns true and will not cause the pop-up to show.
Unlike your and mine original program, the certificate sticks without having to go to the trouble of letting it stick yourself, so I analysed the differences with the demo. One of the differences I noticed was that the demo didn't have a reference to CertMaker.dll and BCMakeCert.dll. After removing these references from my own solution, I got the same behaviour as the demo.
Unfortunately, I don't have an explanation to why this works, but I hope this still helps some people.