Connecting to a SFTP server in Java
10 Feb 2012Working in a financial environment, a lot of transfers are done using different ways.
One of these way is file transfer, usually done using FTP protocol. However FTP protocol is absolutely not secured (data and password are in clear over the network).
The operational choice is often SFTP. SFTP (SSH File Transfer Protocol) is not FTP over SSH, but a rather new protocol, designed since the beginning by working group IETF SECSH. SFTP is a communication protocol running above SSH, do not confuse with File Transfer Protocol over SSL, FTPS.
The goal of this post is to write a piece of code to connect to a SFTP server, upload a file and dlownload another file. We will of course write a unit test and for this task, we will use an embedded SFTP server.
The client : Jsch
Jsch is a 100% Java implementation of SSH2.
This library will allow us to communicate with a SFTP server. Authentication with this kind of server may done done in 2 ways (do not forget SFTP is SSH, so we will find common stuff) :
- login and password
- login and private key (whose public key has been previously registered on the server)
In this article, we will use login/password authentication (because it’s simpler to implement).
A SFTP server for local development
For coding, I advise you to use a little SFTP server, executed on your workstation : miniSFTPServer is a very light simple SFTP server, allowing you to work locally.
You just have to launch it, then configure a lort, a login, a password and a root path.
SFTP connection
SFTP server is now up & running : let’s start coding !
Connecting to the server is quite easy :
jsch = new JSch();
session = jsch.getSession(login, server, port);
// Java 6 version
session.setPassword(password.getBytes(Charset.forName("ISO-8859-1")));
// Java 5 version
// session.setPassword(password.getBytes("ISO-8859-1"));
Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Then, you have to add a com.jcraft.jsch.Channel of type “sftp” (which is a com.jcraft.jsch.ChannelSftp once the channel is accepted) :
// Initializing a channel
channel = session.openChannel("sftp");
channel.connect();
c = (ChannelSftp) channel;
Uploading a file
This is quite simple again : the previously created Channel gives us a method put :
c.put(sourceFile, destinationFile);
This code is using the 2-parameters version. This method exists in a lot of versions, check them to find the best one for your use case.
File downloading
Same player shoot again : the same Channel has a get method :
c.get(sourceFile, destinationFile);
Disconnection
As every Java stream, it’s important to close the Channel, then the Session in order to disconnect properly !
Unit testing : Mina SSHD
Mina project is offering a very interesting sub-module for unit testing SFTP servers : SSHD.
We will use SSHD to start an in-memory SFTP server which will enable us to test our SFTP client.
@Before
In a setUp method (annotated with @Before), we will start a org.apache.sshd.SshServer
@Before
public void setUp() throws IOException {
// Init sftp server stuff
sshd = SshServer.setUpDefaultServer();
sshd.setPort(port);
sshd.setPasswordAuthenticator(new MyPasswordAuthenticator());
sshd.setPublickeyAuthenticator(new MyPublickeyAuthenticator());
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
sshd.setCommandFactory(new ScpCommandFactory());
sshd.start();
...
...
}
Method setUpDefaultServer() automatically preconfigures the SshServer. You just have to add the listening port, implement a very simple PasswordAuthenticator and a ,em>PublicKeyAuthenticator</em>.
Hard part is the next one : adding a ChannekSftp is not easy.
sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
Once server is started, the unit test is very easy to write.
@After
Do not forget to shutdown the SshServer at the end of the unit tests execution :
sshd.stop();
Source Code
You can get all this code with comments and logs in a Maven project :
https://github.com/jpbriend/sftp-example
If you liked this post, you can share it with your followers or follow me on Twitter!