java - 通过显式 SSL/TLS 在 FTP 上登录成功但无法浏览文件

标签 java ssl ftp

我被要求建立安全的 FTP 服务器连接。通过显式 TLS/SSL 的 FTP。为了实现这一点,我在现有的实现中添加了一行。这是我的 FTPClient 库 - it.sauronsoftware.ftp4j - 版本 1.6.1

ftpClient.setSecurity(FTPClient.SECURITY_FTPES);

//现有代码

ftpClient.setConnector(new HTTPTunnelConnector(proxyHost, proxyPort)); ftpClient.connect(getFtpHost(), getFtpPort()); ftpClient.login(getUsername(), getPassword()); ftpClient.setAutoNoopTimeout(30000);

当我在 JBOSS 5.1 上部署代码时,连接成功,但无法列出根目录中的文件。我们只有访问根目录的权限。

另一方面,我编写了一个独立的客户端(java 主程序)——通过它我可以打印 FTP 位置的文件,通过这种方式我确保了安全连接和 FTP 位置的文件可用性。在这里,我使用了

我的问题是,当我通过部署的应用程序建立安全连接时,我无法在远程位置找到任何文件。即:FTPFiles.length 为 0

非常感谢任何帮助,谢谢!

添加更多日志和信息, 未添加 FTPES 安全参数的正常流程(当前实现)

打印 ftpClient.serverStatus()

msg: Status of 'FTP Service' msg: Connected from ec2-xyz msg: Logged in as <user> msg: TYPE: BINARY, STRUcture: File, Mode: Stream msg: Total bytes transferred for session: 10511 msg: No data connection msg: End of status

打印 ftpClient.serverStatus() 添加了 FTPES

msg: Status of 'FTP Service' msg: Connected from ec2-xyz msg: Logged in as <user> msg: TYPE: ASCII, STRUcture: File, Mode: Stream msg: No data connection msg: End of status

我需要知道答案的几个问题(可能会导致修复):

  1. 在这里,TYPE: BINARY 已更改为 ASCII,谁能告诉我如何修改回 BINARY?请注意,没有进行明确的设置,在设置 FTPES 后进行了更改
  2. 此问题是否与代理/端口有关。如果是这样 - 我将无法提供这些信息。
  3. 截至目前,我正在使用应用程序中使用的相同代理进行测试。
  4. 是否需要导入任何证书才能查看/下载文件。
  5. 在网上找到这个与我的问题完全相同,http://www.proftpd.org/docs/howto/TLS.html (搜索 -“我可以使用 FTPS 登录,但我看不到任何目录。为什么不呢?”)但我需要解释我的第三方以进行所需的更改......我应该告诉什么?

独立客户端代码

import it.sauronsoftware.ftp4j.*;
import javax.net.ssl.*;
import java.io.File;
import java.security.*;
import java.util.List;

public class FTPWithSSL {
    private static FTPClient ftpClient;
    private static FTPConfig ftpConfig;
    private DailyFTPConfig config;

    public static void main(String args[]) throws Exception {

        ftpConfig = new FTPConfig("username", "password", "FTPServer.net", 21, setupConnector());

        FTPDownloader ftpDownloader = new FTPDownloader(ftpConfig, new FTPDownloadController() {
            @Override
            public List<FTPFile> download(FTPClient ftpClient) throws Exception {
                downloadFile(ftpClient);
                System.out.println("download success");
                return null;
            }
        });
        try {
            openConnection();
            List<FTPFile> ftpFileList = ftpDownloader.download();
            closeConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void openConnection() throws Exception {
        System.out.println("OpenConnection method");
        if (ftpClient == null) {
            ftpClient = new FTPClient();
            // Even if the below line is commented, the code works fine
            ftpClient.setSSLSocketFactory(getSSLSocketFactory());

            System.out.println("setting FTPES here");
            ftpClient.setSecurity(FTPClient.SECURITY_FTPES);
            ftpClient.setConnector(ftpConfig.getConnector());
            ftpClient.connect(ftpConfig.getFtpHost(), ftpConfig.getFtpPort());
            ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword());
            ftpClient.setAutoNoopTimeout(30000);
            System.out.println("ftpClient.isConnected() " + ftpClient.isConnected());
        }
    }

    private static SSLSocketFactory getSSLSocketFactory() throws Exception {
        TrustManager[] trustManager = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        } };
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustManager, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        return sslSocketFactory;

    }
    private static void closeConnection() throws Exception {
        System.out.println("ftpClient.serverStatus() -- ");
        for (String serverStatus : ftpClient.serverStatus()) {
            System.out.println(" msg: " + serverStatus);
        }
        if (ftpClient != null && ftpClient.isConnected()) {
            ftpClient.disconnect(false);
        }
    }

    private static void downloadFile(FTPClient ftpClient) throws Exception {
        System.out.println("ftpsClient.currentDirectory() " + ftpClient.currentDirectory());
        FTPFile[] ftpFile = ftpClient.list();
        System.out.println("Name " + ftpFile[0].getName());
        System.out.println("Link " + ftpFile[0].getLink());
        System.out.println("Modified Date " + ftpFile[0].getModifiedDate());


        String[] listnames = ftpClient.listNames();
        System.out.println("ftpsClient.listNames() " +listnames);

        System.out.println("ftpsClient.currentDirectory() " + ftpClient.list());
        File file = new File( "C:\\opt\\copycat\\a1234.zip");
        System.out.println("Downloading File: [" + file.getName() + "] has started.");
        ftpClient.download("a1234.zip", file);
        System.out.println("Downloading File: has Completed");
    }

    private static FTPConnector setupConnector() {
        FTPConnector connector = new DirectConnector();
        String proxyHost = "amazonaws.com";
        if (proxyHost != null) {
            System.out.println("proxy host NOT NULL");
            int proxyPort = Integer.parseInt("123");
            connector = new HTTPTunnelConnector(proxyHost, proxyPort);
        }
        return connector;
    }
}

最佳答案

最后,我能够建立安全连接并能够使用 FTPES(通过显式 TLS/SSL 的 FTP)从 FTP 服务器下载最新文件。 在实际实现中,我只更改了 2 行代码(如下)。之前它有 list() 方法从 FTP 服务器获取文件,它的返回类型是 FTPFile[]

这是我所做的代码更改,其他行代码被修改/删除。

    ftpClient.setSecurity(FTPClient.SECURITY_FTPES);
// get the FTP connection
    String[] fileNames = ftpClient.listNames();

// Exisitng implementation
FTPFile[] ftpFiles = ftpClient.list("*.zip");
// after that there is an implementation for getting the latest files using the Comparator<FTPFile>

LIST 命令的输出有问题,即:LIST *.zip 没有给出正确的输出(我猜)

关于java - 通过显式 SSL/TLS 在 FTP 上登录成功但无法浏览文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50340857/

相关文章:

java - 在 JSP 或 CQ5 中获取 url 减去当前文件名

java - 仅添加新表时的房间数据库迁移

c# - 从服务器 xamarin.android 收到的证书无效

java - Java 程序中 SSLKEYLOGFILE 的等价物是什么?

python - 如何在指定时间后中止并重试 ftp 下载?

java - 使用注释验证构造函数参数或方法参数,并让它们自动抛出异常

java - 什么算法在只有 < 的静态方法中运行 T 类型定义?超T> <?扩展 T> 参数?

java - 如何通过 SSL 连接 PostgreSQL 数据库?

azure - centos7 azure 盒子上 vsftpd 登录错误

C# FileSystemWatcher 和 FTP