Podczas łączenia się z udziałem sieciowym, dla którego bieżący użytkownik (w moim przypadku użytkownik usług sieciowych) nie ma żadnych praw, należy podać nazwę i hasło.
Wiem jak to zrobić z funkcjami Win32 ( WNet*
rodzina od mpr.dll
), ale chciałbym to zrobić z funkcjonalnością .Net (2.0).
Jakie opcje są dostępne?
Może więcej informacji pomaga:
- Przypadek użycia to usługa systemu Windows, a nie aplikacja Asp.Net.
- Usługa działa na koncie, które nie ma uprawnień do udziału.
- Konto użytkownika potrzebne do udziału nie jest znane po stronie klienta.
- Klient i serwer nie są członkami tej samej domeny.
Odpowiedzi:
Możesz zmienić tożsamość wątku lub P / Invoke WNetAddConnection2. Wolę to drugie, ponieważ czasami muszę zachować wiele poświadczeń dla różnych lokalizacji. Zawijam go w IDisposable i wywołuję WNetCancelConnection2, aby później usunąć kredyty (unikając błędu wielu nazw użytkowników):
źródło
Tak bardzo podobała mi się odpowiedź Marka Bracketta , że zrobiłem własną szybką implementację. Oto, jeśli ktoś w pośpiechu tego potrzebuje:
źródło
throw new Win32Exception(result);
, ponieważ WNetAddConnection2 zwraca kody błędów win32 (ERROR_XXX
)NetworkCredential
obiektu, aby aplikacja mogła połączyć się raz z dyskiem sieciowym. Następnie otrzymywaliśmy ERROR_LOGON_FAILURE przy każdej próbie do momentu ponownego uruchomienia aplikacji. Próbowaliśmy następnie podać domenę również naNetworkCredential
obiekcie i nagle zadziałało! Nie mam pojęcia, dlaczego to rozwiązało problem, zwłaszcza fakt, że udało się połączyć raz bez domeny.Dzisiaj 7 lat później mam do czynienia z tym samym problemem i chciałbym udostępnić moją wersję rozwiązania.
Jest gotowy do kopiowania i wklejania :-) Oto on:
Krok 1
W twoim kodzie (ilekroć musisz zrobić coś z uprawnieniami)
Krok 2
Plik pomocnika, który robi magię
źródło
Przeszukałem wiele metod i zrobiłem to po swojemu. Musisz otworzyć połączenie między dwoma urządzeniami za pomocą wiersza polecenia polecenie NET USE, a po zakończeniu pracy wyczyść połączenie za pomocą wiersza polecenia NET USE „myconnection” / delete.
Musisz użyć procesu wiersza polecenia z tyłu kodu w następujący sposób:
Użycie jest proste:
Oto funkcje:
A także funkcja ExecuteCommand to:
Ta funkcja działała dla mnie bardzo szybko i stabilnie.
źródło
Rozwiązanie Luke Quinane wygląda dobrze, ale działało tylko częściowo w mojej aplikacji ASP.NET MVC. Mając dwa udziały na tym samym serwerze z różnymi danymi uwierzytelniającymi, mogłem użyć personifikacji tylko dla pierwszego.
Problem z WNetAddConnection2 polega również na tym, że zachowuje się inaczej w różnych wersjach systemu Windows. Dlatego szukałem alternatyw i znalazłem funkcję LogonUser . Oto mój kod, który działa również w ASP.NET:
Stosowanie:
źródło
Dla VB.lovers odpowiednik VB.NET kodu Luke'a Quinane'a (dzięki Luke!)
źródło
Jedną z opcji, że praca może jest za pomocą
WindowsIdentity.Impersonate
(i zmienić głównego wątku), aby stać się żądany użytkownika, jak tak . Wróćmy jednak do p / invoke, obawiam się ...Inną bezczelną (i równie daleką od ideału) opcją może być odrodzenie procesu wykonywania pracy ...
ProcessStartInfo
akceptuje.UserName
,.Password
i.Domain
.Wreszcie - może uruchomić usługę na dedykowanym koncie, które ma dostęp?(usunięty, ponieważ wyjaśniłeś, że nie jest to opcja).źródło
OK ... mogę ponownie odpowiedzieć ..
Oświadczenie: Właśnie miałem ponad 18 godzinny dzień (znowu) .. Jestem stary i zapominam .. Nie mogę przeliterować .. Mam krótki okres uwagi, więc lepiej odpowiedzieć szybko .. :-)
Pytanie:
Czy można zmienić nazwę użytkownika wątku na użytkownika bez konta na komputerze lokalnym?
Odpowiedź:
Tak, możesz zmienić nazwę wątku, nawet jeśli używane poświadczenia nie są zdefiniowane lokalnie lub znajdują się poza „lasem”.
Właśnie natknąłem się na ten problem podczas próby połączenia się z serwerem SQL z uwierzytelnianiem NTLM z usługi. To połączenie wykorzystuje dane uwierzytelniające powiązane z procesem, co oznacza, że do uwierzytelnienia się potrzebujesz konta lokalnego lub konta domeny. Bla bla...
Ale...
Wywołanie LogonUser (..) z atrybutem ???? _ NEW_CREDENTIALS zwróci token zabezpieczający bez próby uwierzytelnienia poświadczeń. Kewl .. Nie musisz definiować konta w „lesie”. Po uzyskaniu tokena może być konieczne wywołanie DuplicateToken () z opcją włączenia personifikacji, co powoduje powstanie nowego tokena. Teraz wywołaj SetThreadToken (NULL, token); (Może to być & token?) .. Wywołanie do ImpersonateLoggedonUser (token); może być wymagane, ale nie sądzę. Sprawdź to ...
Rób, co musisz zrobić ...
Wywołaj RevertToSelf (), jeśli wywołałeś ImpersonateLoggedonUser (), a następnie SetThreadToken (NULL, NULL); (Myślę ... spójrz w górę), a następnie CloseHandle () na utworzonych uchwytach ..
Żadnych obietnic, ale to zadziałało dla mnie ... To jest poza moją głową (jak moje włosy) i nie mogę przeliterować !!!
źródło
Jeśli nie możesz utworzyć lokalnie ważnego tokena zabezpieczającego, wygląda na to, że wykluczyłeś wszystkie interfejsy Win32 API paska opcji i WNetAddConnection *.
Mnóstwo informacji o MSDN na temat WNet - informacje PInvoke i przykładowy kod, który łączy się ze ścieżką UNC tutaj:
Odnośnik MSDN tutaj:
źródło
Przeniesiony również na F # do użycia z FAKE
źródło
Powinieneś rozważyć dodanie czegoś takiego:
W twój web.config.
Więcej informacji.
źródło