Bei der Verbindung zu einer Netzwerkfreigabe, für die der aktuelle Benutzer (in meinem Fall ein netzwerkfähiger Dienstbenutzer) keine Rechte hat, müssen Name und Kennwort angegeben werden.
Ich weiß, wie man das mit Win32-Funktionen (der WNet*
Familie von mpr.dll
) macht, möchte es aber mit .Net (2.0) -Funktionalität machen.
Welche Optionen stehen zur Verfügung?
Vielleicht helfen noch ein paar Informationen:
- Der Anwendungsfall ist ein Windows-Dienst, keine Asp.Net-Anwendung.
- Der Dienst wird unter einem Konto ausgeführt, das keine Rechte an der Freigabe hat.
- Das für die Freigabe erforderliche Benutzerkonto ist auf der Clientseite nicht bekannt.
- Client und Server sind nicht Mitglieder derselben Domäne.
Antworten:
Sie können entweder die Thread-Identität ändern oder WNetAddConnection2 aufrufen. Ich bevorzuge letzteres, da ich manchmal mehrere Anmeldeinformationen für verschiedene Standorte verwalten muss. Ich verpacke es in ein IDisposable und rufe WNetCancelConnection2 auf, um die Creds anschließend zu entfernen (um den Fehler mit mehreren Benutzernamen zu vermeiden):
quelle
Die Antwort von Mark Brackett hat mir so gut gefallen, dass ich meine eigene schnelle Implementierung durchgeführt habe. Hier ist es, wenn jemand anderes es in Eile braucht:
quelle
throw new Win32Exception(result);
, da WNetAddConnection2 win32-Fehlercodes (ERROR_XXX
)NetworkCredential
Objekt konnte die Anwendung einmal eine Verbindung zum Netzlaufwerk herstellen. Danach erhielten wir bei jedem Versuch eine ERROR_LOGON_FAILURE , bis die Anwendung neu gestartet wurde. Wir haben dann versucht, die Domain auch für dasNetworkCredential
Objekt bereitzustellen, und plötzlich hat es funktioniert! Ich habe keine Ahnung, warum dies das Problem behoben hat, insbesondere die Tatsache, dass es funktioniert hat, eine Verbindung ohne die Domain einmal herzustellen.Heute, 7 Jahre später, stehe ich vor dem gleichen Problem und möchte meine Version der Lösung teilen.
Es ist fertig zum Kopieren und Einfügen :-) Hier ist es:
Schritt 1
In Ihrem Code (wann immer Sie etwas mit Berechtigungen tun müssen)
Schritt 2
Die Helfer-Datei, die eine Magie macht
quelle
Ich habe viele Methoden gesucht und es auf meine eigene Weise gemacht. Sie müssen eine Verbindung zwischen zwei Computern über den Befehl NET USE der Eingabeaufforderung herstellen und nach Beendigung Ihrer Arbeit die Verbindung mit der Eingabeaufforderung NET USE "myconnection" / delete löschen.
Sie müssen den Eingabeaufforderungsprozess aus dem folgenden Code verwenden:
Die Verwendung ist einfach:
Hier sind Funktionen:
Die ExecuteCommand-Funktion lautet außerdem:
Diese Funktionen haben bei mir sehr schnell und stabil funktioniert.
quelle
Die Luke Quinane-Lösung sieht gut aus, hat aber in meiner ASP.NET MVC-Anwendung nur teilweise funktioniert. Mit zwei Freigaben auf demselben Server mit unterschiedlichen Anmeldeinformationen konnte ich den Identitätswechsel nur für die erste verwenden.
Das Problem mit WNetAddConnection2 ist auch, dass es sich unter verschiedenen Windows-Versionen unterschiedlich verhält. Deshalb habe ich nach Alternativen gesucht und die LogonUser- Funktion gefunden. Hier ist mein Code, der auch in ASP.NET funktioniert:
Verwendung:
quelle
Für VB.lovers das VB.NET-Äquivalent von Luke Quinanes Code (danke Luke!)
quelle
Eine Option, die möglicherweise funktioniert, ist die Verwendung
WindowsIdentity.Impersonate
(und Änderung des Thread-Prinzips), um der gewünschte Benutzer zu werden . Zurück zu p / invoke, fürchte ich ...Eine andere freche (und ebenso weit vom Ideal entfernte) Option könnte darin bestehen, einen Prozess zu erzeugen, um die Arbeit zu erledigen ...
ProcessStartInfo
akzeptiert ein.UserName
,.Password
und.Domain
.Schließlich - vielleicht den Dienst in einem dedizierten Konto ausführen, das Zugriff hat?(entfernt, da Sie klargestellt haben, dass dies keine Option ist).quelle
OK ... ich kann resond ..
Haftungsausschluss: Ich hatte gerade einen Tag mit mehr als 18 Stunden (wieder). Ich bin alt und vergesslich. Ich kann nicht buchstabieren. Ich habe eine kurze Aufmerksamkeitsspanne, also reagiere ich besser schnell. :-)
Frage:
Ist es möglich, das Thread-Prinzip in einen Benutzer ohne Konto auf dem lokalen Computer zu ändern?
Antworten:
Ja, Sie können einen Thread-Principal ändern, auch wenn die von Ihnen verwendeten Anmeldeinformationen nicht lokal definiert sind oder sich außerhalb der "Gesamtstruktur" befinden.
Ich bin gerade auf dieses Problem gestoßen, als ich versucht habe, über einen Dienst eine Verbindung zu einem SQL Server mit NTLM-Authentifizierung herzustellen. Bei diesem Aufruf werden die mit dem Prozess verknüpften Anmeldeinformationen verwendet. Dies bedeutet, dass Sie entweder ein lokales Konto oder ein Domänenkonto zur Authentifizierung benötigen, bevor Sie sich als Benutzer ausgeben können. Bla, bla ...
Aber...
Wenn Sie LogonUser (..) mit dem Attribut ???? _ NEW_CREDENTIALS aufrufen, wird ein Sicherheitstoken zurückgegeben, ohne dass versucht wird, die Anmeldeinformationen zu authentifizieren. Kewl .. Sie müssen das Konto nicht innerhalb der "Gesamtstruktur" definieren. Sobald Sie das Token haben, müssen Sie möglicherweise DuplicateToken () mit der Option aufrufen, den Identitätswechsel zu aktivieren, was zu einem neuen Token führt. Rufen Sie nun SetThreadToken (NULL, Token) auf. (Es könnte & Token sein?) .. Ein Aufruf von ImpersonateLoggedonUser (Token); könnte erforderlich sein, aber ich denke nicht. Schlag es nach..
Tun Sie, was Sie tun müssen ..
Rufen Sie RevertToSelf () auf, wenn Sie ImpersonateLoggedonUser () aufgerufen haben, dann SetThreadToken (NULL, NULL); (Ich denke ... nachschlagen) und dann CloseHandle () auf den erstellten Handles.
Keine Versprechungen, aber das hat bei mir funktioniert ... Das ist mir auf den Kopf gefallen (wie meine Haare) und ich kann nicht buchstabieren !!!
quelle
Wenn Sie kein lokal gültiges Sicherheitstoken erstellen können, haben Sie anscheinend alle Optionsleisten Win32 API und WNetAddConnection * ausgeschlossen.
Tonnenweise Informationen zu MSDN über WNet - PInvoke-Informationen und Beispielcode, der hier eine Verbindung zu einem UNC-Pfad herstellt:
MSDN Referenz hier:
quelle
Wird auch auf F # portiert , um mit FAKE verwendet zu werden
quelle
Sie sollten versuchen, ein solches hinzuzufügen:
In Ihre web.config.
Mehr Informationen.
quelle