目前我正在使用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);