簡體   English   中英

有沒有一種方法可以使用FtpWebRequest使用C#中的客戶端證書對FTP進行身份驗證?

[英]Is there a way to use FtpWebRequest to authenticate to FTP using client certificates in C#?

我正在嘗試將文件上傳到FTP服務器,並且需要使用客戶端證書進行身份驗證,而不是用戶名和密碼。

var fullFtpPath = String.Concat(ftpItem.FtpAddress, "/", record, ".txt");

FtpWebRequest request = (FtpWebRequest) WebRequest.Create(fullFtpPath);
request.Credentials = new NetworkCredential(ftpItem.Username, ftpItem.Password);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.UsePassive = ftpItem.UsePassive;
request.EnableSsl = ftpItem.UseSSL;

request.ContentLength = bytes.Length;
using(Stream s = request.GetRequestStream()) {
    s.Write(bytes, 0, bytes.Length);
}

FtpWebResponse response = (FtpWebResponse) request.GetResponse();
Debug.WriteLine("Upload File Complete, status {0}", response.StatusDescription);

db.LogExport(siteId, fullFtpPath, record, true, response.StatusDescription);
response.Close();

上面是我當前的代碼,但是我不確定如何實現證書身份驗證,甚至不確定是否可以執行。 我必須創建證書嗎? 還是服務器將向我提供證書,而我將在請求中進行設置?

FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com");

request.Credentials = new NetworkCredential("username", "");

// Query certificate from store
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
const string tp = "2b6f8ac51a85cbaf429474a55304313968667611";
X509Certificate2 cert2 =
    store.Certificates.Find(X509FindType.FindByThumbprint, tp, true)[0];
store.Close();

// Add certificate into request
request.ClientCertificates.Add(cert2);

您可以為此使用ComponentPro 此代碼示例說明如何使用證書對客戶端進行身份驗證:

using System;
using System.Security.Cryptography.X509Certificates;
using ComponentPro.Net;

...

public void HandleCertificateRequiredEvent()
{
    // Create a new instance.
    Ftp client = new Ftp();

    client.CertificateRequired += client_CertificateRequired;

    // Connect to the FTP server.
    client.Connect("myserver", 21, FtpSecurityMode.Explicit);

    // Authenticate.
    client.Authenticate("userName", "password");

    // Do something here...
    client.DownloadFile("/my remote file.dat", "my local file");

    // Disconnect.
    client.Disconnect();
}

void client_CertificateRequired(object sender, ComponentPro.Security.CertificateRequiredEventArgs e)
{
    // Load certificates from the local machine.
    X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    my.Open(OpenFlags.ReadOnly);

    // Retrieve a list of available certificates.
    X509Certificate2Collection certs = my.Certificates;

    // If no certificate found, return.
    if (certs.Count == 0)
    {
        e.Certificates = null;
        return;
    }

    // Show all certificates.
    Console.WriteLine("Select certificate:");
    for (int i = 0; i <= certs.Count; i++)
    {
        if (i == 0)
        {
            Console.WriteLine(string.Format("{0}. [Nothing, skip this step]", i));
            continue;
        }

        Console.WriteLine(string.Format("{0}. {1}", i, certs[i - 1].SubjectName.Name));
    }

    // And ask user to choose an appropriate certificate.
    while (true)
    {
        Console.Write(string.Format("Select certificate [0 - {0}]: ", certs.Count));

        int certIndex;

        try
        {
            certIndex = int.Parse(Console.ReadLine());
        }
        catch
        {
            Console.WriteLine("ERROR: Wrong certificate index input!");
            continue;
        }

        if (certIndex > 0 && certIndex <= certs.Count)
        {
            e.Certificates = new X509Certificate2Collection(certs[certIndex]);
            return;
        }

        if (certIndex == 0)
            break;

        Console.WriteLine(string.Format("ERROR: You must enter number between 0 and {0}.", certs.Count));
    }
}

ComponentPro也可以與FtpWebRequest一起使用

using System;
using System.IO;
using System.Net;

...

// Register FtpWebRequest for the specified schema.
WebRequest.RegisterPrefix("ftp://", ComponentPro.Net.FtpWebRequest.Creator);

Console.WriteLine("Sending request...");

// Create a WebRequest for the specified URL.
WebRequest request = WebRequest.Create("ftp://ftp.example.net/pub/myfile.zip");

// Send the WebRequest and waits for a response.
WebResponse response = request.GetResponse();

// Get remote file stream for downloading.
Stream remoteFileStream = response.GetResponseStream();

Stream localFileStream = File.Create("myfile.zip");

// Create a new buffer to download.
byte[] buffer = new byte[1024];
int n;
do
{
    // Read data from the remote file stream.
    n = remoteFileStream.Read(buffer, 0, buffer.Length);
    // Write to the local file stream.
    localFileStream.Write(buffer, 0, n);
} while (n > 0);

Console.WriteLine("Response Received.");

localFileStream.Close();

// Release the resources of the response.
remoteFileStream.Close();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM