javaspringspring-bootspring-integration-sftp

Getting "A password must be configured on the externally provided SshClient instance" While trying to transfer file using "spring-integration-sftp"


Getting below while trying to transfer file via SFTP using spring-integration-sftp approach.

Error

org.apache.sshd.common.SshException: Unable to negotiate key exchange for kex algorithms.

With other approach(JSch) I'm able to transfer file to remote server.

SftpConfig.java

@Configuration
public class SftpConfig{
    @Value("${sftp.host}")
    private String host;
    @Value("${sftp.port}")
    private int port;
    @Value("${sftp.user}")
    private String user;
    @Value("${sftp.password}")
    private String password;
    @Value("${sftp.remoteDirectory}")
    private String remoteDirectory;

    @Bean
    public SessionFactory<SftpClient.DirEntry> sftpSessionFactory(){
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost(host);
    factory.setPort(port);
    factory.setUser(user);
    HostConfigEntry hostConfigEntry = new HostConfigEntry("",host,port,user);
    hostConfigEntry.setProperty("StrictHostKeyChecking","no");
    hostConfigEntry.setProperty("PreferredAuthentications","password");
    factory.setHostConfig(hostConfigEntry);
    factory.setPassword(password);
    factory.setAllowedUnknownKeys(true);
    return new CachingSessionFactory(factory,0)
    }

    @Bean(name="toSftpChannelTesting")
    @ServiceActivator(inputChannel = "toChannelTesting")
    public NessageHandler testingMessageHandler(){
    SftpMessageHandler handlr = new  SftpMessageHandler(sftpSessionFactory());
    handlr.setRemoteDirectoryExpression(new LiteralExpression(remoteDirectory));
    handlr.setAutoCreateDirectory(false);
    handlr.setUseTemproryFileName(false);
    return handler;
    }
}
    

FileUploadAdapter.java

@Service
public class FileUploadAdapter{
    @AutoWired private TransferGateway transferGateway;
    @Retryable(
    retryFor = RetryException.class, maxAttempts = 2,
    backoff = @Backoff(delay = 3000))
    pubic void transferTestFile(File file){
        transferGateway.transferTestFile(file);
    }
}

TransferGateway.java

@MessagingGateway
public interface TransferGateway{
    @Gateway(requestChannel = "toChannelTesting")
    void transferTestFile(File file);
}

I had tried doing as per the details in below link

Spring Integration SFTP connection fails - Unable to negotiate key exchange for kex algorithms

But I'm getting below error java.lang.IllegalStateException: A password must be configured on the externally provided SshClient instance

I want to use Preferred Authentication as password

Is there anything wrong I'm doing here.

Any help with this is much appreciated. Thanks!


Solution

  • Issue got resolved after modifying like below

    @Bean public SessionFactory<SftpClient.DirEntry> sftpSessionFactory(){

    SshClient client = SshClient.setUpDefaultClient();
    client.setKeyExchangeFactories(NamedFactory.setUpTransformedFactories(
    false,
    BuiltinDHFactories.VALUES,
    ClientBuilder.DH2KEX));
    client.setSignatureFactories(new ArrayList<>(BuiltinSignatures.VALUES));
    client.addPasswordIdentity(password);
    
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(client,true);
    factory.setHost(host);
    factory.setPort(port);
    factory.setUser(user);
    return new CachingSessionFactory(factory,0)
    

    }