47

所以我正在写一个小程序,需要通过SFTP连接到远程服务器,拉下一个文件,然后处理这个文件。我在这里通过一些答案遇到了 JSch,它看起来非常适合这项任务。到目前为止,易于使用并且我已经让它工作了,我想修复一件小事。我正在使用以下代码连接并拉下文件:

    JSch jsch = new JSch();
    Session session = null;
    try {
        session = jsch.getSession("username", "127.0.0.1", 22);
        session.setConfig("StrictHostKeyChecking", "no");
        session.setPassword("password");
        session.connect();

        Channel channel = session.openChannel("sftp");
        channel.connect();
        ChannelSftp sftpChannel = (ChannelSftp) channel;
        sftpChannel.cd(REMOTE_FTP_DIR);
        sftpChannel.lcd(INCOMING_DIR);
        sftpChannel.get(TMP_FILE, TMP_FILE);
        sftpChannel.exit();
        session.disconnect();
    } catch (JSchException e) {
        e.printStackTrace();
    } catch (SftpException e) {
        e.printStackTrace();
    }

所以这行得通,我得到了文件。我在 linux 服务器上运行此代码,当我运行代码时,JSch 会询问我的 Kerberos 用户名和密码。看起来像:

Kerberos 用户名 [乔治]:

乔治的 Kerberos 密码:

我对这两个问题都按了 Enter 键,然后程序似乎继续运行,没有任何问题。但是,我需要通过 cron 任务自动执行此代码,因此我不想让它暂停程序来问我这两个问题。有什么我没有提供的,所以它不会问这个吗?我需要做些什么来阻止它问?希望有人有一些想法。谢谢。

4

3 回答 3

85

以为我会在这里发布答案,因为以防其他人最终遇到类似问题。原来我错过了一段让一切变得不同的代码。我只需要添加

session.setConfig("PreferredAuthentications", 
                  "publickey,keyboard-interactive,password");

session.connect();

现在一切正常。

于 2012-06-04T17:24:31.270 回答
12

虽然自我接受的答案中的解决方案是正确的,但它缺乏任何解释。

问题是 OP 将 Kerberos/GSSAPI 身份验证设置为首选(JSch 默认值)。然而 OP 似乎并没有真正使用/想要它,因为 OP 声称没有为 Kerberos 提示指定任何用户名或密码。

当 Kerberos 安装在客户端 PC 上或服务器开始支持 Kerberos 时,此问题可能会自发出现。

解决方案是从 JSch 中的首选身份验证方法列表中删除 Kerberos/GSSAPI ( gssapi-with-mic):

session.setConfig(
    "PreferredAuthentications", "publickey,keyboard-interactive,password");
于 2017-04-20T07:31:02.530 回答
0

所有答案都是正确的,我将在此处添加尝试与 SFTP 服务器集成时 Spring Integration 可以完成的方式。

因此,如果您使用的是 SFTP Spring Integration,并且 Kerberos 的奇怪用户和密码会以与 OP 要求相同的方式进行提示。

然后修改您的 Spring 配置(我使用的是 Java Spring Integration 配置,如果您使用的是 XML 配置,您可以尝试自己翻译它 - 我真的不喜欢 XML 配置:P):

因此,在您用作 SessionFactory 的 bean 中,您需要在配置中添加此更改:

@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost("hostname");
    factory.setPort(22);
    factory.setUser("username");
    factory.setPassword("superstrongpassword");
    factory.setAllowUnknownKeys(true);
    factory.setSessionConfig(buildSessionProperties());
    return new CachingSessionFactory<>(factory);
}

/**
 * Build JSch property PreferredAuthentications without "gssapi-with-mic"
 * This way it won't prompt for Kerberos authentication every time it tries to connect
 * to the SFTP.
 */
private Properties buildSessionProperties() {
    Properties sessionProperties = new Properties();
    sessionProperties.setProperty("PreferredAuthentications", "publickey,keyboard-interactive,password");
    return sessionProperties;
}
于 2020-09-25T16:09:26.960 回答