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

Java Apache Mina SFTP服务器端传入文件的通道侦听器,java,listener,sftp,apache-mina,Java,Listener,Sftp,Apache Mina,我正试图找出如何为基于Java的SFTP服务器实现服务器端侦听器,以便在传入文件传输时提醒我。我使用的是ApacheMina的最新版本。我的场景是,我的服务器只需从客户端接收一个文件,并在存储该文件之前对其进行“处理”。可能是错误检查/规则验证/将内容转发到其他地方。问题是我想在它被保存到我的系统之前就这么做。我在文档方面遇到了困难,并且找不到一个可以显示通过访问传入文件流实现的侦听器的工作示例。我有一个非常简单的服务器,取自指南: public void setupServer() throw

我正试图找出如何为基于Java的SFTP服务器实现服务器端侦听器,以便在传入文件传输时提醒我。我使用的是ApacheMina的最新版本。我的场景是,我的服务器只需从客户端接收一个文件,并在存储该文件之前对其进行“处理”。可能是错误检查/规则验证/将内容转发到其他地方。问题是我想在它被保存到我的系统之前就这么做。我在文档方面遇到了困难,并且找不到一个可以显示通过访问传入文件流实现的侦听器的工作示例。我有一个非常简单的服务器,取自指南:

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();
}
public void setupServer()引发IOException{
sshd=SshServer.setUpDefaultServer();
setFileSystemFactory(新的NativeFileSystemFactory(){
@凌驾
公共文件系统视图createFileSystemView(最终会话){
返回新的NativeFileSystemView(session.getUsername(),false){
@凌驾
公共字符串getVirtualUserDir(){
返回testFolder.getRoot().getAbsolutePath();
}
};
};
});
sshd.setPort(8001);
sshd.setSubsystemFactorys(阵列
.asList(新的sftpusbsystem.Factory());
setCommandFactory(新的ScpCommandFactory());
setKeyPairProvider(新的SimpleGeneratorHostKeyProvider(testFolder
.newFile(“hostkey.ser”).getAbsolutePath();
setPasswordAuthenticator(新的PasswordAuthenticator(){
公共布尔认证(最终字符串用户名、最终字符串密码、,
最终服务器会话(会话){
返回StringUtils.equals(用户名、用户名)
&&StringUtils.equals(密码、密码);
}
});
//SessionListener事件=新建SessionListener();
sshd.start();
}
该服务器能够接收文件并将其存储在虚拟文件系统中。我可以读取文件/验证内容,但只能在收到并存储文件后进行。基本的身份验证现在还可以,感谢您,身份验证机制的文档记录非常好

所以我的问题是:

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

  • 我是否需要设置一个侦听器,以便在新文件出现时观察目录并相应地处理它
提前谢谢!
Leigh.

您似乎认为SFTP类似于HTTP协议。也就是说,客户端打开一个与“write”请求的连接(比如HTTP PUT),发送请求体的文件内容,断开连接,就这样

SFTP不是这样工作的

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

影响:

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

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

    • 派生
      NativeFileSystemView
    • 派生
      NativeSshFile
    • 重写
      NativeFileSystemView.createNativeSshFile
      以创建
      NativeSshFile
    • 重写NativeFileSystemView.isWritable()
  • 无法重定向SFTP连接。SSH/SFTP不支持连接“重定向”(与HTTP不同)

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