简体   繁体   English

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

[英]Apache Mina SFTP server side channel listener for incoming files

I am trying to figure out how to implement Server side listeners for a Java based SFTP server to alert me to an incoming file transfer.我想弄清楚如何为基于 Java 的 SFTP 服务器实现服务器端侦听器,以提醒我注意传入的文件传输。 I'm using the latest version of Apache Mina.我正在使用最新版本的 Apache Mina。 My scenario is for my server to simply receive a file from a client and do "something" to the file before storing it.我的方案是让我的服务器简单地从客户端接收一个文件,并在存储之前对该文件执行“某些操作”。 That something could be error checking / rules validation / forwarding the contents elsewhere.这可能是错误检查/规则验证/将内容转发到其他地方。 The thing is I want to do that before it is saved on my system.问题是我想在它保存在我的系统上之前这样做。 I'm having difficulty with the documentation and can't find a working example that shows a listener implemented with access to the incoming file stream.我在文档方面遇到了困难,并且找不到一个工作示例,该示例显示了通过访问传入文件流实现的侦听器。 I have a very simple server taken from a guide:我从指南中获取了一个非常简单的服务器:

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();
}

That server is capable of receiving a file and storing it on the virtual file system.该服务器能够接收文件并将其存储在虚拟文件系统上。 I can read the file / verify the contents but only after the file is received and stored.我可以读取文件/验证内容,但只有在收到并存储文件之后。 Basic authentication is fine for now, the authentication mechanisms are really well documented thankfully!基本身份验证现在很好,值得庆幸的是,身份验证机制确实有据可查!

So my question is:所以我的问题是:

  • Is there a means to check dynamically when a connection is being made / when the contents are being transferred and to intercept that as it is happening ie before the file is actually committed to a directory.是否有办法动态检查何时建立连接/何时传输内容并在文件实际提交到目录之前拦截它。

or要么

  • Will I need to setup a listener to simply watch a directory for new files as they appear and process it accordingly?我是否需要设置一个监听器来简单地观察新文件出现的目录并相应地处理它?

Thanks in advance!提前致谢! Leigh.利。

You seem to have an idea that the SFTP is similar protocol to an HTTP.您似乎知道 SFTP 是类似于 HTTP 的协议。 Ie the client opens a connection with "write" request (like HTTP PUT), sends a file contents of request body, disconnects and that's it.即客户端打开一个带有“写”请求的连接(如 HTTP PUT),发送请求正文的文件内容,断开连接,就是这样。

That's not how the SFTP works.这不是 SFTP 的工作方式。

The SFTP is like a remote file system. SFTP 就像一个远程文件系统。 The client connects to the SSH/SFTP server and keeps the connection open.客户端连接到 SSH/SFTP 服务器并保持连接打开。 During the session, the client sends an "open" file request (with either read or write or both privileges) and gets a handle to the opened file.在会话期间,客户端发送“打开”文件请求(具有读或写权限或两者兼有)并获取打开文件的句柄。 Then it sends a sequence of read/write-block requests using the file handle.然后它使用文件句柄发送一系列读/写块请求。 And finally it closes the handle.最后它关闭手柄。 During a single session, the client can (and typically does) read/write or both any number of files it likes.在单个会话期间,客户端可以(并且通常会)读取/写入它喜欢的任意数量的文件。 It can even have several files opened in parallel, accessing them in a completely random order.它甚至可以并行打开多个文件,以完全随机的顺序访问它们。 It is very similar to a way an application works with a local file system.它与应用程序使用本地文件系统的方式非常相似。

Implications:含义:

  • You cannot reject connection when you do not like a file, because the connection request itself is not associated with a specific file.当您不喜欢某个文件时,您不能拒绝连接,因为连接请求本身与特定文件无关。 All you can is reject the file "open" (or "create") request.您所能做的就是拒绝文件“打开”(或“创建”)请求。

    One way to intercept a file open/create request:拦截文件打开/创建请求的一种方法:

    • Derive NativeFileSystemView .派生NativeFileSystemView
    • Derive NativeSshFile .派生NativeSshFile
    • Override NativeFileSystemView.createNativeSshFile to create your NativeSshFile覆盖NativeFileSystemView.createNativeSshFile以创建您的NativeSshFile
    • Override NativeFileSystemView.isWritable()覆盖NativeFileSystemView.isWritable()
  • You cannot redirect an SFTP connection.您无法重定向 SFTP 连接。 SSH/SFTP does not support connection "redirect" (unlike HTTP) SSH/SFTP 不支持连接“重定向”(与 HTTP 不同)

  • There's not a single moment where you have a complete file in a memory at once, so that you can inspect it somehow.没有一个时刻您可以立即在内存中拥有一个完整的文件,以便您可以以某种方式检查它。 Instead the client sends the file in chunks.相反,客户端以块的形式发送文件。 You can of course reimplement the MINA SFTP "input stream" in a way that it keeps the file contents in a memory and inspect a complete contents once you get a "close" request;您当然可以重新实现 MINA SFTP“输入流”,将文件内容保存在内存中,并在收到“关闭”请求后检查完整内容; saving the file to a disk only once you are happy with the file.只有在您对文件感到满意后才将文件保存到磁盘。 Beware of DOS attacks though.不过要小心 DOS 攻击。


A protocol that is more close to what you imagine is the SCP, which also runs over SFTP.更接近您想象的协议是 SCP,它也通过 SFTP 运行。 For it, there's ScpTransferEventListener .对于它,有ScpTransferEventListener

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM