Bir bilgisayardan ağdaki diğer bir bilgisayara C Sharp ile güvenli dosya transferi nasıl yapılır?

Kasım 2011 | Hakan Köse, İnternet Girişimcisi
Geçtiğimiz günlerde bir şekilde internette uzun bir süre araştırma yapmama rağmen çok etkili bir sonuç bulamadığım bir konudan bahsetmek istiyorum. Başlıktan da anlayacağınız üzere konu 'Dosya Transferi'.

Web uygulamalarında File Upload işlemi bilinen ve kullanımı/geliştirilmesi kolay olan bir model ancak aynı ihtiyacı Windows Application için karşılamaya kalktığınızda durum biraz zorlaşıyor.

Çünkü, IIS üzerinde yetkilere sahip bir web user oluşturarak rahatça çözümleyebildiğiniz bir yetkilendirme sorunu, Local Network içinde sadece bir kullanıcı hesabı açmakla çözümlenmiyor.

Senaryo şu şekildeydi:

  • Kullanıcı uygulamayı açıp bilgisayarından seçtiği bir dosyayı sisteme yükleyecek
  • Uygulama tarafından yüklenen bu dosya Yerel Ağ içinde bulunan bir ana makineye yazılacak
  • Bunları gerçekleştirirken Client makinelerin kullanıcıları hiçbir şekilde ana makinede bulunan bu Folder'lara erişim sağlayamayacak

Burada sorun yaratan şey ise; Client'ın Authenticate olmadan ana makineye erişememesi ve eğer authenticate olabiliyor ise dosyalara da erişebiliyor olacağıydı. Yani, dosyalara erişim için farklı bir hesap açmak ve yazılım tarafında geçici olarak (sadece dosya alışverişi esnasında) bu ayrı hesap üzerinden login olmayı sağlamak ve iş bittikten sonra bu izinlendirmeyi Client'tan kaldırmak gerekiyor.


Nette çok fazla bu konuda kod ve makale var ancak ben size şimdiden optimum ve performanslı çalışan çözümü (en azından benim için öyle) paylaşayım:


Önce bağlantıyı açacak, transferi yapacak ve bağlantıyı kapatacak fonksiyon:

public static void SaveACopyfileToServer(string filePath, string savePath)
{
var directory = Path.GetDirectoryName(savePath).Trim();
var username = "loginusername";
var password = "loginpassword";
var filenameToSave = Path.GetFileName(savePath);

if (!directory.EndsWith("\\\\"))
filenameToSave = "\\\\" + filenameToSave;

var command = "NET USE " + directory + " /delete";
ExecuteCommand(command, 5000);

command = "NET USE " + directory + " /user:" + username + " " + password;
ExecuteCommand(command, 5000);

command = " copy \\"" + filePath + "\\" \\"" + directory + filenameToSave + "\\"";

ExecuteCommand(command, 5000);


command = "NET USE " + directory + " /delete";
ExecuteCommand(command, 5000);
}


Ardından komutu işleten fonksiyon fonksiyon:

public static int ExecuteCommand(string command, int timeout)
{
var processInfo = new ProcessStartInfo("cmd.exe", "/C " + command)
{
CreateNoWindow = true,
UseShellExecute = false,
WorkingDirectory = "C:\\\\",
};

var process = Process.Start(processInfo);
process.WaitForExit(timeout);
var exitCode = process.ExitCode;
process.Close();
return exitCode;
}


Bu fonksiyonların kullanım şekli ise şu şekilde:

var savePath = @"\\\\servername\\foldername\\myfilename.jpg";
var filePath = @"C:\\\\temp\\myfileTosave.jpg";

SaveACopyfileToServer(filePath, savePath);

Umarım ihtiyacınızı karşılar, vakit bulursam performans ölçümlerini de yapıp paylaşacağım.

Kodla ilgili tüm yorumlarınızı memnuniyetle bekliyorum.

NOT: Ayrıca kodları da içeren bir yorum bıraktığım teknik bağlantıyı da burada bulabilirsiniz: stackoverflow.com/questions/295538/how-to-provide-user-name-and-password-when-connecting-to-a-network-share/8271759#8271759