Wir sind in eine interessante Situation geraten, die gelöst werden muss, und meine Suchanfragen sind nicht aufgetaucht. Ich appelliere daher an die SO-Community um Hilfe.
Das Problem ist folgendes: Wir müssen programmgesteuert auf eine freigegebene Datei zugreifen, die sich nicht in unserer Domäne befindet und sich nicht über Remote File Sharing / UNC in einer vertrauenswürdigen externen Domäne befindet. Natürlich müssen wir dem Remote-Computer Anmeldeinformationen bereitstellen.
Normalerweise löst man dieses Problem auf zwei Arten:
- Ordnen Sie die Dateifreigabe als Laufwerk zu und geben Sie die Anmeldeinformationen zu diesem Zeitpunkt an. Dies erfolgt normalerweise mit dem
NET USE
Befehl oder den duplizierten Win32-FunktionenNET USE
. - Greifen Sie mit einem UNC-Pfad auf die Datei zu, als ob sich der Remotecomputer in der Domäne befindet, und stellen Sie sicher, dass das Konto, unter dem das Programm ausgeführt wird, als lokaler Benutzer auf dem Remotecomputer dupliziert wird (einschließlich Kennwort). Nutzen Sie grundsätzlich die Tatsache, dass Windows automatisch die Anmeldeinformationen des aktuellen Benutzers bereitstellt, wenn der Benutzer versucht, auf eine freigegebene Datei zuzugreifen.
- Verwenden Sie keine Remote-Dateifreigabe. Verwenden Sie FTP (oder ein anderes Mittel), um die Datei zu übertragen, arbeiten Sie lokal daran und übertragen Sie sie dann zurück.
Aus verschiedenen Gründen haben unsere Sicherheits- / Netzwerkarchitekten die ersten beiden Ansätze abgelehnt. Der zweite Ansatz ist offensichtlich eine Sicherheitslücke; Wenn der Remotecomputer kompromittiert wird, ist der lokale Computer jetzt gefährdet. Der erste Ansatz ist unbefriedigend, da das neu gemountete Laufwerk eine gemeinsam genutzte Ressource ist, die anderen Programmen auf dem lokalen Computer während des Dateizugriffs durch das Programm zur Verfügung steht. Auch wenn es durchaus möglich ist, dies vorübergehend zu machen, ist es dennoch ein Loch in ihrer Meinung.
Sie stehen der dritten Option offen, aber die Remote-Netzwerkadministratoren bestehen eher auf SFTP als auf FTPS, und FtpWebRequest unterstützt nur FTPS. SFTP ist die Firewall-freundlichere Option, und es gibt einige Bibliotheken, die ich für diesen Ansatz verwenden könnte, aber ich würde es vorziehen, meine Abhängigkeiten zu reduzieren, wenn ich kann.
Ich habe MSDN nach einem verwalteten oder einem Win32-Mittel für die Verwendung der Remote-Dateifreigabe durchsucht, aber ich habe nichts Nützliches gefunden.
Und so frage ich: Gibt es einen anderen Weg? Habe ich eine supergeheime win32-Funktion verpasst, die macht, was ich will? Oder muss ich eine Variante von Option 3 verfolgen?
quelle
Antworten:
Um Ihr Problem zu lösen, verwenden Sie eine Win32-API namens WNetUseConnection .
Verwenden Sie diese Funktion, um eine Verbindung zu einem UNC-Pfad mit Authentifizierung herzustellen und NICHT um ein Laufwerk zuzuordnen .
Auf diese Weise können Sie eine Verbindung zu einem Remotecomputer herstellen, auch wenn dieser sich nicht in derselben Domäne befindet und einen anderen Benutzernamen und ein anderes Kennwort hat.
Sobald Sie WNetUseConnection verwendet haben, können Sie über einen UNC-Pfad auf die Datei zugreifen, als wären Sie in derselben Domäne. Der beste Weg ist wahrscheinlich durch die administrativen eingebauten Aktien.
Beispiel: \\ Computername \ c $ \ Programme \ Ordner \ Datei.txt
Hier ist ein Beispiel für einen C # -Code, der WNetUseConnection verwendet.
Beachten Sie, dass Sie für NetResource für lpLocalName und lpProvider null übergeben sollten. Der dwType sollte RESOURCETYPE_DISK sein. Der lpRemoteName sollte \\ Computername sein.
quelle
WNetUseConnection
denen geöffnet wurde , manuell durch Aufrufen geschlossen werdenWNetCancelConnection2
? Oder gibt es eine Leerlaufzeit (oder einen anderen Mechanismus) und wir müssen uns nicht darum kümmern?Für Leute, die nach einer schnellen Lösung suchen, können Sie das verwenden, was
NetworkShareAccesser
ich kürzlich geschrieben habe (basierend auf dieser Antwort (vielen Dank!)):Verwendung:
WARNUNG: Bitte stellen Sie unbedingt sicher, dass
Dispose
dieNetworkShareAccesser
aufgerufen wird (auch wenn Ihre App abstürzt!), Andernfalls bleibt eine offene Verbindung unter Windows bestehen. Sie können alle offenen Verbindungencmd
anzeigen, indem Sie die Eingabeaufforderung öffnen und eingebennet use
.Der Code:
quelle
using System.Runtime.InteropServices;
undusing System.ComponentModel;
fürDllImport
undWin32Exception
AFAIK, die Sie nicht benötigen Karte den UNC - Pfad zu einem Laufwerksbuchstaben , um Anmeldeinformationen für einen Server herzustellen. Ich habe regelmäßig Batch-Skripte verwendet wie:
Jedes Programm, das auf demselben Konto wie Ihr Programm ausgeführt wird, kann jedoch weiterhin auf alles zugreifen, auf
username:password
das Zugriff hat. Eine mögliche Lösung könnte darin bestehen, Ihr Programm in einem eigenen lokalen Benutzerkonto zu isolieren (der UNC-Zugriff ist lokal für das aufgerufene KontoNET USE
).Hinweis: Die Verwendung von SMB über Domänen hinweg ist für die IMO-Technologie keine gute Verwendung. Wenn Sicherheit so wichtig ist, ist die Tatsache, dass SMB nicht verschlüsselt ist, für sich genommen ein Dämpfer.
quelle
NET USE
ist, ist dies möglicherweise ein praktikabler Ansatz. Sind Sie sicher, dass wir ein lokales Konto verwenden müssen? Wäre derNET USE
Anruf nicht lokal für den Computer, auf dem er angerufen wurde? Sie haben mir einen guten Forschungsweg gegebenAnstelle von WNetUseConnection würde ich NetUseAdd empfehlen . WNetUseConnection ist eine Legacy-Funktion, die von WNetUseConnection2 und WNetUseConnection3 abgelöst wurde. Alle diese Funktionen erstellen jedoch ein Netzwerkgerät, das im Windows Explorer angezeigt wird. NetUseAdd entspricht dem Aufruf der Netznutzung in einer DOS-Eingabeaufforderung zur Authentifizierung auf einem Remotecomputer.
Wenn Sie NetUseAdd aufrufen, sollten nachfolgende Versuche, auf das Verzeichnis zuzugreifen, erfolgreich sein.
quelle
Obwohl ich mich selbst nicht kenne, würde ich sicherlich hoffen, dass # 2 falsch ist ... Ich würde gerne glauben, dass Windows meine Anmeldeinformationen (am allerwenigsten mein Passwort!) AUTOMATISCH nicht an einen Computer weitergibt geschweige denn eine, die nicht zu meinem Vertrauen gehört.
Haben Sie die Identitätswechselarchitektur untersucht? Ihr Code wird ungefähr so aussehen:
In diesem Fall ist die
token
Variable ein IntPtr. Um einen Wert für diese Variable zu erhalten, müssen Sie die nicht verwaltete LogonUser Windows-API-Funktion aufrufen. Eine kurze Reise zu pinvoke.net gibt uns die folgende Signatur:Benutzername, Domain und Passwort sollten ziemlich offensichtlich sein. Schauen Sie sich die verschiedenen Werte an, die an dwLogonType und dwLogonProvider übergeben werden können, um den Wert zu ermitteln, der Ihren Anforderungen am besten entspricht.
Dieser Code wurde nicht getestet, da ich hier keine zweite Domain habe, in der ich überprüfen kann, aber dies sollte Sie hoffentlich auf den richtigen Weg bringen.
quelle
Hier wurde eine minimale POC-Klasse mit der gesamten Kruft entfernt
Sie können
\\server\share\folder
w / direkt verwendenWNetUseConnection
, ohne es\\server
vorher nur abisolieren zu müssen.quelle
Die meisten SFTP-Server unterstützen auch SCP, für das Bibliotheken viel einfacher zu finden sind. Sie können sogar einfach einen vorhandenen Client aus Ihrem Code wie pscp aufrufen, der in PuTTY enthalten ist .
Wenn der Dateityp, mit dem Sie arbeiten, so einfach wie eine Text- oder XML-Datei ist, können Sie sogar Ihre eigene Client / Server-Implementierung schreiben, um die Datei mithilfe von .NET Remoting oder Webdiensten zu bearbeiten.
quelle
Ich habe gesehen, dass Option 3 mit JScape-Tools auf ziemlich einfache Weise implementiert wurde . Sie könnten es versuchen. Es ist nicht kostenlos, aber es macht seinen Job.
quelle
Ich füge meinen vb.net Code basierend auf Brian Referenz hinzu
wie man es benutzt
quelle
Ich suchte bei MS nach Antworten. Bei der ersten Lösung wird davon ausgegangen, dass das Benutzerkonto, auf dem der Anwendungsprozess ausgeführt wird, Zugriff auf den freigegebenen Ordner oder das freigegebene Laufwerk (dieselbe Domäne) hat. Stellen Sie sicher, dass Ihr DNS aufgelöst ist, oder verwenden Sie die IP-Adresse. Gehen Sie einfach wie folgt vor:
Wenn Sie .NET 2.0 mit Anmeldeinformationen für verschiedene Domänen verwenden möchten, gehen Sie wie folgt vor:
quelle