我被要求建立安全的FTP服务器连接。 FTP通过显式TLS / SSL。为了实现这一点,我在现有实现中添加了以下行。这是我的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
我需要知道答案的几个问题(可能会导致修复):
独立客户代码
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;
}
}
答案 0 :(得分:0)
最后,我能够建立安全连接,并能够使用FTPES(FTP over explicit TLS / SSL)从FTP服务器下载最新文件。 在实际实现中,我只做了2行代码更改(下面)。之前它使用list()方法从FTP服务器获取文件,其返回类型为FTPFile []
这是我所做的代码更改,其他代码行被修改/删除。
var theLIst = document.getElementById('list');
var resetNotify = document.getElementById('reset-message');
var st = window.localStorage;
var nameArray = [];
theLIst.innerHTML = JSON.parse(st.getItem('names'));
function addName() {
resetNotify.innerHTML = '';
var name = document.getElementById('names');
nameArray = JSON.parse(st.getItem('names'));
if ( nameArray != null) {
nameArray.join('');
nameArray.push("<p>" + name.value + "</p>");
} else {
console.log('The Array has been purged. Resetting.')
nameArray = [];
nameArray.push("<p>" + name.value + "</p>");
}
st.setItem("names", JSON.stringify(nameArray));
console.log(nameArray);
name.value = '';
theLIst.innerHTML = JSON.parse(st.getItem('names'));
}
function clearArray() {
st.clear();
nameArray = [];
console.log(nameArray);
theLIst.innerHTML = '';
resetNotify.innerHTML = 'Array has been purged.';
}
LIST命令的输出存在问题,即:LIST * .zip没有给出正确的输出(我猜)