2012-12-03 24 views
13

Tôi đang sử dụng JGit để truy cập repo Git từ xa và tôi cần sử dụng SSH cho nó. JGit sử dụng JSch để cung cấp quyền truy cập an toàn. Tuy nhiên, tôi không chắc chắn làm thế nào để thiết lập các tập tin quan trọng và các tập tin máy chủ biết cho JGit. Những gì tôi đã thử là như sau.Sử dụng các Phím với JGit để Truy cập vào Kho lưu trữ Git An toàn

Tạo một cấu hình tùy chỉnh của SshSessionFactory, sử dụng bởi subclassing JSchConfigSessionFactory:

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

Trong lớp mà tôi truy cập vào Git repo từ xa, đã làm như sau:

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

tôi không thể tìm ra cách liên kết đối tượng JSch này với JGit để nó có thể kết nối thành công với kho lưu trữ từ xa. Khi tôi cố gắng sao chép nó với JGit, tôi nhận được ngoại lệ sau đây:

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 

Tôi đã thêm mục git.test.com đến file /etc/hosts tôi. Tôi đã sử dụng cùng một mã để truy cập vào một repo git với một địa chỉ http, do đó, mã nó hoạt động tốt. Đó là phần xử lý chính thất bại. Bất kỳ ý tưởng về cách xử lý này?

Trả lời

3

Được quản lý để tìm sự cố. Khóa công khai ở phía máy chủ có tên khác với id_rsa.pub thông thường, trong khi khóa riêng tư ở bên cạnh tôi là id_rsa. JSch hy vọng theo mặc định khóa công khai có cùng tên với khóa riêng cộng với hậu tố .pub. Sử dụng cặp khóa có tên chung (ví dụ: private = key_1 và public = key_1.pub) sẽ giải quyết được vấn đề.

11

Bạn cần phải ghi đè lên các phương pháp getJSch trong lớp nhà máy tùy chỉnh của bạn:

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 là quan trọng; nó dường như không hoạt động mà không có nó.

Thông báo trước: Tôi đã viết ở trên trong Scala, và sau đó dịch nó sang Java, vì vậy nó có thể không hoàn toàn đúng. Scala ban đầu là như sau:

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

Vấn đề của tôi là tôi cần thiết để có thể xác định các cụm từ mật khẩu cho khóa bí mật, mà bạn có thể thêm như một tham số cho 'addIdentity' hoặc bằng cách tạo riêng của bạn lớp thực hiện 'UserInfo' và sau đó đặt tham số' session' thành phương thức 'configure' của' CustomConfigSessionFactory' để sử dụng 'UserInfo' đó. – WhiteKnight

+2

Cảm ơn đặc biệt cho gợi ý 'jsch.removeAllIdentity()'! – Vincent

4

Jsch sesems để không giống như một tập tin known_hosts trong băm dưới định dạng nó phải phù hợp với các định dạng được sản xuất bởi:

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

ví dụ

<hostname> ssh-rsa <longstring/longstring> 

không:

|1|<hashed hostname>= ecdsa-sha2-nistp256 <hashed fingerprint>= 
Các vấn đề liên quan