In this article we will connect to SFTP server using username and SSH key as the authentication method.
We will use Apache's VFS library to establish the connection.
Following class show how to:
- Connect to SFTP server
- Navigate to a desired folder
- List of files in a folder
First we need to add the Apache VFS dependency to our project. For maven it can be added to the pom.xml file.
Latest dependency can be found at: https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-vfs2</artifactId><version>2.9.0</version></dependency>
Now let's look at the actual code, in SftpWithSshKey class below.
/*** This class uses Apache's VFS project to connect to remote SFTP server using* username and SSH key based authentication.* <p>* Maven Dependency: https://mvnrepository.com/artifact/org.apache.commons/commons-vfs2* Apache Commons-VFS Project: https://commons.apache.org/proper/commons-vfs/*/public class SftpWithSshKey {public static final String SFTP = "sftp";/*** Holds instance of remote SFTP folder.*/private FileObject fileObject;/*** Direct instantiation not allowed. Use {@link #connect(String, Integer, String, File, String)}* method to initiate connection.** @param fileObject*/private SftpWithSshKey(FileObject fileObject) {this.fileObject = fileObject;}/*** Initiate connection to remote SFTP server** @param host* @param port* @param userName* @param sshKey - file containing the SSH private Key* @param passphrase - Passphrase of SSH private key* @return*/public static SftpWithSshKey connect(String host,Integer port,String userName,File sshKey,String passphrase) throws URISyntaxException, FileSystemException {URI sftpUri = createSftpUri(host, port, userName);FileSystemOptions options = new FileSystemOptions();SftpFileSystemConfigBuilder sftpConfigBuilder = SftpFileSystemConfigBuilder.getInstance();IdentityProvider identityInfo = new IdentityInfo(sshKey, passphrase.getBytes());sftpConfigBuilder.setIdentityProvider(options, identityInfo);return new SftpWithSshKey(VFS.getManager().resolveFile(sftpUri.toString(), options));}/*** Navigate to specific folder in SFTP** @param folderPath* @return*/public SftpWithSshKey cd(String folderPath) throws FileSystemException {if (this.fileObject == null) {throw new RuntimeException("SFTP connection not initiated.");}FileObject newFolder = this.fileObject.resolveFile(folderPath);if (!newFolder.exists() || !newFolder.isFolder()) {throw new RuntimeException("Path does not exist or is not a folder.");}this.fileObject = newFolder;return this;}/*** List all file names. Only file names are listed, not the folders.** @return*/public List<String> listFiles() throws FileSystemException {return ofNullable(this.fileObject.findFiles(SELECT_FILES)).map(Arrays::asList).orElseGet(Collections::emptyList).stream().map(FileObject::getName).map(FileName::getBaseName).collect(Collectors.toList());}/*** Create SFTP URI** @param host* @param port* @param userName* @return*/private static URI createSftpUri(String host,Integer port,String userName) throws URISyntaxException {return new URI(SFTP, userName, host, Objects.requireNonNullElse(port, -1), null, null, null);}}
Sample usage of the SftpWithSshKey class would be as below
/*** Sample usage of {@link SftpWithSshKey} class*/class SftpWithSshKeyTest {/*** Test that all files in movies folder are listed.** @throws URISyntaxException* @throws FileSystemException*/public void listAllFiles() throws URISyntaxException, FileSystemException {File privateKey = new File("~/.ssh/ida_rsa");List<String> files = SftpWithSshKey.connect("localhost", 22, "admin", privateKey, "passphrase").cd("./documents").listFiles();Assertions.assertEquals(2, files.size());}}
0 comments:
Post a Comment