2012-12-03 2 views
13

J'utilise JGit pour accéder à un dépôt Git distant, et je dois utiliser SSH pour cela. JGit utilise JSch pour fournir un accès sécurisé. Cependant, je ne suis pas sûr de savoir comment définir le fichier de clé et le fichier hosts de JGit. Ce que j'ai essayé est le suivant.Utilisation de clés avec JGit pour accéder à un référentiel Git en toute sécurité

créé une configuration personnalisée du SshSessionFactory, en utilisant par le sous-classement JSchConfigSessionFactory:

public class CustomJschConfigSessionFactory extends JschConfigSessionFactory { 
    @Override 
    protected void configure(OpenSshConfig.Host host, Session session) { 
     session.setConfig("StrictHostKeyChecking", "yes"); 
    } 
} 

Dans la classe que j'accéder à la git à distance, a fait ce qui suit:

CustomJschConfigSessionFactory jschConfigSessionFactory = new CustomJschConfigSessionFactory(); 

JSch jsch = new JSch(); 
try { 
    jsch.addIdentity(".ssh/id_rsa"); 
    jsch.setKnownHosts(".ssh/known_hosts"); 
} catch (JSchException e) { 
    e.printStackTrace(); 
} 
    SshSessionFactory.setInstance(jschConfigSessionFactory); 

Je ne peux pas Découvrez comment associer cet objet JSch à JGit pour qu'il puisse se connecter avec succès au référentiel distant. Lorsque je tente de cloner avec JGit, je reçois l'exception suivante:

org.eclipse.jgit.api.errors.TransportException: [email protected]:abc.org/test_repo.git: reject HostKey: git.test.com 
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:137) 
at org.eclipse.jgit.api.CloneCommand.fetch(CloneCommand.java:178) 
at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:125) 
at GitTest.cloneRepo(GitTest.java:109) 
at GitTest.main(GitTest.java:223) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
at java.lang.reflect.Method.invoke(Method.java:597) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: org.eclipse.jgit.errors.TransportException: [email protected]:abc.org/test_repo.git: reject HostKey: git.test.com 
at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:142) 
at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:121) 
at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:248) 
at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:147) 
at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:136) 
at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:122) 
at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1104) 
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:128) 
... 9 more 
Caused by: com.jcraft.jsch.JSchException: reject HostKey: git.test.com 
at com.jcraft.jsch.Session.checkHost(Session.java:748) 
at com.jcraft.jsch.Session.connect(Session.java:321) 
at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:116) 
... 16 more 

J'ai ajouté l'entrée de git.test.com à mon dossier /etc/hosts. J'ai utilisé le même code pour accéder à un repo git avec une URL http, donc le code fonctionne très bien. C'est la partie de manipulation de clé qui échoue. Une idée sur la façon de gérer cela?

Répondre

3

Géré pour trouver le problème. La clé publique du côté serveur avait un nom différent de l'habituel id_rsa.pub, tandis que la clé privée de mon côté était id_rsa. JSch attend par défaut que la clé publique ait le même nom que la clé privée plus le suffixe .pub. L'utilisation d'une paire de clés avec un nom commun (ex .: private = key_1 et public = key_1.pub) résout le problème.

11

Vous devez remplacer la méthode getJSch dans votre classe d'usine personnalisée:

class CustomConfigSessionFactory extends JschConfigSessionFactory 
{ 
    @Override 
    protected JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException { 
     JSch jsch = super.getJSch(hc, fs); 
     jsch.removeAllIdentity(); 
     jsch.addIdentity("/path/to/private/key"); 
     return jsch; 
    } 
} 

Calling jsch.removeAllIdentity est importante; ça ne semble pas fonctionner sans ça. Une mise en garde: J'ai écrit ce qui précède dans Scala, puis l'ai traduit vers Java, donc ce n'est peut-être pas tout à fait correct. La Scala originale est la suivante:

class CustomConfigSessionFactory extends JschConfigSessionFactory 
{ 
    override protected def getJSch(hc : OpenSshConfig.Host, fs : FS) : JSch = 
    { 
     val jsch = super.getJSch(hc, fs) 
     jsch.removeAllIdentity() 
     jsch.addIdentity("/path/to/private/key") 
     jsch 
    } 
} 
+1

Mon problème était que je devais être en mesure de préciser le mot de passe pour la clé privée, que vous pouvez ajouter un autre paramètre à 'addIdentity' ou en créant votre propre class qui implémente 'UserInfo', puis définit le paramètre' session' sur la méthode 'configure' de' CustomConfigSessionFactory' pour utiliser 'UserInfo'. – WhiteKnight

+2

Un merci spécial pour l'indice 'jsch.removeAllIdentity()'! – Vincent

4

jsch sesems à pas comme un fichier known_hosts dans le hashed format-- il doit être conforme au format produit par:

ssh-keyscan -t rsa hostname >> ~/.ssh/known_hosts

par exemple

<hostname> ssh-rsa <longstring/longstring> 

pas:

|1|<hashed hostname>= ecdsa-sha2-nistp256 <hashed fingerprint>= 
Questions connexes