java - 传入文件的 Apache Mina SFTP 服务器端 channel 监听器

标签 java listener sftp apache-mina

我正在尝试弄清楚如何为基于 Java 的 SFTP 服务器实现服务器端监听器,以提醒我传入的文件传输。我正在使用最新版本的 Apache Mina。我的方案是让我的服务器简单地从客户端接收文件并在存储文件之前对该文件执行“某些操作”。这可能是错误检查/规则验证/将内容转发到其他地方。问题是我想在它保存在我的系统上之前这样做。我在阅读文档时遇到困难,找不到显示通过访问传入文件流实现的监听器的工作示例。我有一个从指南中获取的非常简单的服务器:

public void setupServer() throws IOException {

    sshd = SshServer.setUpDefaultServer();
    sshd.setFileSystemFactory(new NativeFileSystemFactory() {
        @Override
        public FileSystemView createFileSystemView(final Session session) {
            return new NativeFileSystemView(session.getUsername(), false) {
                @Override
                public String getVirtualUserDir() {
                    return testFolder.getRoot().getAbsolutePath();
                }
            };
        };
    });
    sshd.setPort(8001);
    sshd.setSubsystemFactories(Arrays
            .<NamedFactory<Command>> asList(new SftpSubsystem.Factory()));
    sshd.setCommandFactory(new ScpCommandFactory());
    sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(testFolder
            .newFile("hostkey.ser").getAbsolutePath()));
    sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
        public boolean authenticate(final String username, final String password,
                final ServerSession session) {

            return StringUtils.equals(username, USERNAME)
                    && StringUtils.equals(password, PASSWORD);
        }
    });

    // SessionListener event = new SessionListener();

    sshd.start();
}

该服务器能够接收文件并将其存储在虚拟文件系统中。我可以读取文件/验证内容,但只有在接收并存储文件之后。基本身份验证目前还不错,谢天谢地,身份验证机制确实有很好的文档记录!

所以我的问题是:

  • 是否有一种方法可以动态检查何时建立连接/何时传输内容并在发生时拦截它,即在文件实际提交到目录之前。

  • 我是否需要设置一个监听器,以便在新文件出现时简单地监视目录并进行相应处理?

提前致谢! 利。

最佳答案

您似乎认为 SFTP 是类似于 HTTP 的协议(protocol)。 IE。客户端打开一个带有“写入”请求的连接(如 HTTP PUT),发送请求主体的文件内容,断开连接,仅此而已。

SFTP 不是这样工作的。

SFTP 就像一个远程文件系统。客户端连接到 SSH/SFTP 服务器并保持连接打开。在 session 期间,客户端发送一个“打开”文件请求(具有读取或写入或两者的权限)并获得打开文件的句柄。然后它使用文件句柄发送一系列读/写 block 请求。最后它关闭了句柄。在单个 session 期间,客户端可以(并且通常会)读/写或同时读/写任意数量的文件。它甚至可以同时打开多个文件,以完全随机的顺序访问它们。它与应用程序使用本地文件系统的方式非常相似。

影响:

  • 当您不喜欢某个文件时,您不能拒绝连接,因为连接请求本身与特定文件没有关联。您所能做的就是拒绝文件“打开”(或“创建”)请求。

    拦截文件打开/创建请求的一种方法:

    • 派生 NativeFileSystemView
    • 派生 NativeSshFile
    • 覆盖 NativeFileSystemView.createNativeSshFile 以创建您的 NativeSshFile
    • 覆盖 NativeFileSystemView.isWritable()
  • 您不能重定向 SFTP 连接。 SSH/SFTP 不支持连接“重定向”(与 HTTP 不同)

  • 没有一个时刻可以在内存中同时拥有一个完整的文件,以便您可以以某种方式检查它。相反,客户端以 block 的形式发送文件。您当然可以重新实现 MINA SFTP“输入流”,将文件内容保存在内存中,并在收到“关闭”请求后检查完整内容;仅在对文件满意后才将文件保存到磁盘。不过要提防 DOS 攻击。


一个更接近你想象的协议(protocol)是SCP,它也是跑在SSH之上的。为此,有 ScpTransferEventListener

关于java - 传入文件的 Apache Mina SFTP 服务器端 channel 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29698274/

相关文章:

java - 动画听众,听谁的?

android - Dialog 不会在按下按钮时触发关闭监听器

c# - 无法在 C# 中使用 SSH.NET 上传文件 SFTP - 权限被拒绝

powershell - 观察本地文件夹的变化并将它们上传到 SFTP 服务器

java - 使用 PowerMockRunner 而不是使用 MockitoJUnitRunner 时出现 EncryptionInitializationException

java - Spring for Python 与 Spring for Java 相比如何

java - 将 Statement.RETURN_GENERATED_KEYS 与 MS-Access JDBC-ODBC 一起使用会引发异常

java - 向 Android Studio 添加外部库时出现非法参数异常

javascript - 删除子函数事件监听器

php - 通过 SFTP 发送逗号分隔的 CSV?