如何将apachevfs2用于带有公钥和无密码的sftp



目前我正在使用apachevfs2从sftp下载文件。对于身份验证,我使用用户名和密码。

有没有一种方法可以只使用公共私钥而不使用密码的vfs2?

我想我已经用过这个功能了,但是怎么用呢?只设置为"是"?

SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(options, "no");

这是我当前的代码(片段):

private boolean downloadFile(){
    StandardFileSystemManager sysManager = new StandardFileSystemManager();
    //download der Datei
    try {
        sysManager.init();
        FileObject localFile = sysManager.resolveFile(localFilePath);
        FileObject remoteFile = sysManager.resolveFile(createConnectionString(host, user, password, fileName, port),createDefaultOptions());
        //Selectors.SELECT_FILES --> A FileSelector that selects only the base file/folder.
        localFile.copyFrom(remoteFile, Selectors.SELECT_FILES);

    } catch (Exception e) {
        logger.error("Downloading file failed: " + e.toString());
        return false;
    }finally{
        sysManager.close();
    }
    return true;
}

private FileSystemOptions createDefaultOptions() throws FileSystemException{
    //create options for sftp
    FileSystemOptions options = new FileSystemOptions();
    //ssh key
    SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(options, "no");
    //set root directory to user home
    SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(options, true);
    //timeout
    SftpFileSystemConfigBuilder.getInstance().setTimeout(options, timeout);
    return options;
}

获取代码并将其包装成可运行的示例。请注意IdentityInfo的实现。这可以通过更改明显的行来使用带有密码短语的密钥。

$ javac -cp 'jsch-0.1.51.jar;commons-vfs2-2.0.jar' SftpGet.java
$ java -cp 'jsch-0.1.51.jar;commons-vfs2-2.0.jar;commons-logging-1.1.1.jar;.' SftpGet

带有

import java.io.File;
import com.jcraft.jsch.UserInfo;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.Selectors;
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
import org.apache.commons.vfs2.provider.sftp.IdentityInfo;

    public class SftpGet {
        public static void main(String[] args) {
            downloadFile();
        }

        private static boolean downloadFile(){
            String host = "HOSTNAMEHERE";
            String user = "USERNAMEHERE";
            String password = "";
            String fileName = "/lines.txt";
            String localFilePath = "c:/cygwin64/home/woddle/wrote_lines.txt";
            // without passphrase
            String keyPath = "c:/cygwin64/home/woddle/.ssh/id_dsa_nopass";
            String passphrase = null;
            // with passphrase
            // String keyPath = "c:/cygwin64/home/woddle/.ssh/id_dsa_withpass";
            // String passphrase = "super-secrets";
            StandardFileSystemManager sysManager = new StandardFileSystemManager();
            //download der Datei
            try {
                sysManager.init();
                FileObject localFile = sysManager.resolveFile(localFilePath);
                FileObject remoteFile = sysManager.resolveFile(createConnectionString(host, user, password, keyPath, passphrase, fileName), createDefaultOptions(keyPath, passphrase));
                //Selectors.SELECT_FILES --> A FileSelector that selects only the base file/folder.
                localFile.copyFrom(remoteFile, Selectors.SELECT_FILES);

            } catch (Exception e) {
                System.out.println("Downloading file failed: " + e.toString());
                return false;
            }finally{
                sysManager.close();
            }
            return true;
        }

        public static String createConnectionString(String hostName, String username, String password, String keyPath, String passphrase, String remoteFilePath) {
            if (keyPath != null) {
                return "sftp://" + username + "@" + hostName + "/" + remoteFilePath;
            } else {
                return "sftp://" + username + ":" + password + "@" + hostName + "/" + remoteFilePath;
            }
        }

        private static FileSystemOptions createDefaultOptions(final String keyPath, final String passphrase) throws FileSystemException{
            //create options for sftp
            FileSystemOptions options = new FileSystemOptions();
            //ssh key
            SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(options, "no");
            //set root directory to user home
            SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(options, true);
            //timeout
            SftpFileSystemConfigBuilder.getInstance().setTimeout(options, 10000);
            if (keyPath != null) {
                IdentityInfo identityInfo = null;
                if(passPhrase!=null){
                    identityInfo = new IdentityInfo(new File(keyPath), passPhrase.getBytes());
                }else{
                    identityInfo =  new IdentityInfo(new File(keyPath));
                }
          SftpFileSystemConfigBuilder.getInstance().setIdentityInfo(options, identityInfo);
            }

            return options;
        }

    }

我们不应该使用下面的方法来创建连接字符串。这可能会暴露密码。

public static String createConnectionString(String hostName, String username, String password, String keyPath, String passphrase, String remoteFilePath) {
    if (keyPath != null) {
        return "sftp://" + username + "@" + hostName + "/" + remoteFilePath;
    } else {
        return "sftp://" + username + ":" + password + "@" + hostName + "/" + remoteFilePath;
    }
}

根据Apache网站上的文档,我们应该使用

StaticUserAuthenticator auth = new StaticUserAuthenticator("domain", "username", "password");

链接:https://commons.apache.org/proper/commons-vfs/api.html

此外,如果我们使用基于公钥或私钥的身份验证,那么我们应该使用setIdentityInfo(FileSystemOptions, IdentityInfo...)而不是setIdentities(FileSystemOptions opts, File... identityFiles)

参考:https://commons.apache.org/proper/commons-vfs/commons-vfs2/apidocs/org/apache/commons/vfs2/provider/sftp/SftpFileSystemConfigBuilder.html

FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, false);
String openSSHPrivateKey = "C:\Users\<filepath>\id_rsa.key";
IdentityInfo myIdentityInfo = new IdentityInfo(new File(openSSHPrivateKey));
    
SftpFileSystemConfigBuilder.getInstance(). setIdentityInfo(opts, myIdentityInfo);

相关内容

  • 没有找到相关文章

最新更新