Search code examples
javasftpapache-commons-vfs

How to skip password prompt during SFTP using commons-VFS


I am trying to upload file from windows to Linux using apache-commons-vfs API. I am able to upload file using this utility but when program runs, its asking for credentials to enter even its already there in the code. If we enter blank in credentials also, it is allowing to upload.

Is it possible to skip that credentials prompt?

If SSH private/public is the only solution, then please share the steps to do that.

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

import org.apache.commons.vfs2.FileObject;
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;

public class SSHUtility {

    static Properties props;

    public static void main(String[] args) {

        SSHUtility SSHUtility = new SSHUtility();
        if (args.length < 1) {
            System.err.println("Usage: java " + SSHUtility.getClass().getName() + " Properties_file File_To_FTP ");
            System.exit(1);
        }

        String propertiesFile = args[0].trim();
        String fileToFTP = args[1].trim();
        SSHUtility.startFTP(propertiesFile, fileToFTP);

    }

    public boolean startFTP(String propertiesFilename, String fileToFTP) {

        props = new Properties();
        StandardFileSystemManager manager = new StandardFileSystemManager();

        try {

            // props.load(new FileInputStream("properties/" + propertiesFilename));
            props.load(new FileInputStream(propertiesFilename));
            String serverAddress = props.getProperty("serverAddress").trim();
            String userId = props.getProperty("userId").trim();
            String password = props.getProperty("password").trim();
            String remoteDirectory = props.getProperty("remoteDirectory").trim();
            String localDirectory = props.getProperty("localDirectory").trim();

            // check if the file exists
            String filepath = localDirectory + fileToFTP;
            File file = new File(filepath);
            if (!file.exists())
                throw new RuntimeException("Error. Local file not found");

            // Initializes the file manager
            manager.init();

            // Setup our SFTP configuration
            FileSystemOptions opts = new FileSystemOptions();
            SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
            SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
            SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);

            // Create the SFTP URI using the host name, userid, password, remote path and file name
            String sftpUri = "sftp://" + userId + ":" + password + "@" + serverAddress + ":/" + remoteDirectory
                    + fileToFTP;

            // Create local file object
            FileObject localFile = manager.resolveFile(file.getAbsolutePath());

            System.out.println("localFile::::" + file.getAbsolutePath());

            // Create remote file object
            FileObject remoteFile = manager.resolveFile(sftpUri, opts);

            // Copy local file to sftp server
            remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
            System.out.println("File upload successful");

        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        } finally {
            manager.close();
        }

        return true;
    }

}

Solution

  • Setting setPreferredAuthentications as "publickey,keyboard-interactive,password" would resolve this issue.

    // Setup our SFTP configuration
    FileSystemOptions opts = new FileSystemOptions();
    SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
    SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
    SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
    SftpFileSystemConfigBuilder.getInstance().setPreferredAuthentications(opts, "publickey,keyboard-interactive,password");