用于传入文件的 Apache Mina SFTP 服务器端通道侦听器

Posted

技术标签:

【中文标题】用于传入文件的 Apache Mina SFTP 服务器端通道侦听器【英文标题】:Apache Mina SFTP server side channel listener for incoming files 【发布时间】:2015-06-24 06:00:05 【问题描述】:

我试图弄清楚如何为基于 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();

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

所以我的问题是:

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

我是否需要设置一个侦听器来简单地观察目录中出现的新文件并进行相应处理?

提前致谢! 利。

【问题讨论】:

【参考方案1】:

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

这不是 SFTP 的工作方式。

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

启示:

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

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

派生NativeFileSystemView。 派生NativeSshFile。 覆盖NativeFileSystemView.createNativeSshFile 以创建您的NativeSshFile 覆盖NativeFileSystemView.isWritable()

您无法重定向 SFTP 连接。 SSH/SFTP 不支持连接“重定向”(与 HTTP 不同)

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


一个更接近您想象的协议是 SCP,它也通过 SSH 运行。对于它,有ScpTransferEventListener

【讨论】:

以上是关于用于传入文件的 Apache Mina SFTP 服务器端通道侦听器的主要内容,如果未能解决你的问题,请参考以下文章

图解Apache Mina

apache mina 怎么接受xml文件 TextLineCodecFactory 只能接受一行

即时通讯开发Apache Mina框架之IoFilter详解

即时通讯开发Apache Mina框架之IoFilter详解

apache开源java ftp文件服务器mina ftpserver安装部署,Windows

java之网络通信框架mina