2009-05-27 13 views
6

Napisałem aplikację C#, która odblokowuje użytkowników, gdy są zablokowani na swoim koncie (Active Directory). Aplikacja wyszukuje użytkowników w określonej jednostce organizacyjnej i wyświetla listę zablokowanych użytkowników w składniku ComboBox. Następnie wybierz tego użytkownika z ComboBox i wybierz opcję odblokowania.Jak uruchomić aplikację C# z kredytami administracyjnymi?

Jeśli jesteś zalogowany jako administrator, działa idealnie. Jeśli jesteś normalnym użytkownikiem nie.

Chcę uruchomić moją aplikację z uprawnieniami administratora, ale pod normalnym użytkownikiem również tak bezpiecznie, jak to możliwe.

Czytałem, że może programować usługę Windows, ale nie mam pojęcia, jak zaprogramować moją aplikację do zainstalowania, uruchomić jako usługę i uruchomić pod nadzorem administratora.

+0

Czy prawdopodobnie używasz Vista/W7/Server2008 i jesteś zalogowany jako administrator, ale aplikacja uruchamia w/z podniesionymi danymi uwierzytelniającymi? – Nate

+0

to wszystko stacje robocze xp pro, a AD to win2k3 –

Odpowiedz

1

Wygląda na to, że chcesz podszyć się pod administratora.Oto article and demo. Wygląda na napisane w .Net 1, ale powinno zacząć. Sprawdź również klasę WindowsIdentity.

+1

Problem polega na tym, że jest bardzo stary i nieaktualny. Podszywanie się pod dotychczasowego administratora oznacza, że ​​poświadczenia wymagają przekazania, co nie jest idealne, ponieważ wymagają ochrony. – IbrarMumtaz

8

Cel związany z tą aplikacją uderza mnie w błąd. Zasadniczo próbujesz stworzyć sposób na odblokowanie kont przez użytkowników nieadministracyjnych ... co jest, z ważnych powodów, funkcją niedostępną dla zwykłych użytkowników.

+2

Zgadzam się, że zazwyczaj jest to zły pomysł; jednak może on zezwalać użytkownikowi zasilającemu (przedstawicielowi działu wsparcia?) na odblokowywanie innych kont użytkowników bez przyznawania pełnych praw administracyjnych. – Nate

+0

Czy to konkretne pozwolenie nie może zostać przekazane do odpowiedniej grupy? – Rob

0

Nie można używać usługi systemu Windows (w łatwy sposób), ponieważ usługa systemu Windows nie może mieć graficznego interfejsu użytkownika. Jedynym sposobem na zrobienie tego jako usługi byłoby zainstalowanie usługi, a następnie utworzenie aplikacji GUI, która używała IPC do przekazania żądania do usługi. Otworzyłoby to jednak potencjalną lukę prawną.

Jeśli używasz systemu Vista, dobrym rozwiązaniem byłoby edit the manifest file i dodanie requireAdministrator.


Edit:

Brzmi jak moja pierwsza sugestia może być to, co chcesz ... Aby to zrobić, podstawowy proces jest:

  • Złóż podanie usługa systemu Windows. W sieci MSDN znajduje się walkthrough of this process.
  • Uczyń swoją usługę odpowiedzią na jakąś formę IPC. Można użyć gniazd, rur lub dowolnej innej formy komunikacji. Usługa "podsłucha" żądanie odblokowania użytkownika, a następnie wykonaj to.
  • Zainstaluj usługę na urządzeniu. To sprawi, że będzie działał jako administrator i po prostu będzie zawsze włączony.
  • Zrób drugą aplikację, aby działać jako klient. Użyj tej samej technologii IPC do komunikacji z serwerem. Spowoduje to wysłanie żądania odblokowania klienta do usługi.

Następnie można uruchomić klienta jako zwykłego użytkownika (ponieważ musi on tylko rozmawiać z usługą, nie robi niczego, co wymaga uprawnień).

+0

@Reed: Tak zwany jedyny sposób, aby to zrobić, to to, co prawdopodobnie (czy zdaje sobie z tego sprawę, czy nie) chce zrobić. Wymaganie uprawnień administratora można równie łatwo wykonać za pomocą kliknięcia prawym przyciskiem, ale zwykli użytkownicy nie będą mogli uruchomić aplikacji w tym przypadku. – Brian

+0

Tak - zgadzam się jednak z tobą, że ogólnie jest to po prostu zły pomysł ... –

+0

Ja * miałem * to zrobić kilka lat temu, aby użyć określonego interfejsu API portu COM, który działałby tylko dla zaawansowanych użytkowników. . Nie ładne, ale działa. – crashmstr

2

Nie musisz używać usługi Windows, aby zrobić coś jak ktoś inny. Możesz użyć personifikacji, aby zalogować się jako inny użytkownik, aby wykonać rzeczywisty przełącznik. Oto przykład, który znalazłem, który używa biblioteki DLL "advapi32.dll" do logowania.

Złap przykładowy kod u dołu strony. Nie chciałem po prostu skopiować jego kodu tutaj.

http://csharptuning.blogspot.com/2007/06/impersonation-in-c.html

Jeden Cavet z personifikacji jest jednak, że komputer robi personifikacji musi być w tej samej domenie co użytkownik że podszyć.

0

Mam bardzo podobny widżet na mojej stronie intranetowej, więc członkowie działu IT znajdujący się w różnych strefach czasowych mogą obsługiwać resetowanie hasła, które wykonuje także odblokowanie konta, gdy administratorzy domeny na zachodnim wybrzeżu nie są dostępni. Jest to dość proste zadania i tutaj jest wyjątkiem od tego, jak to zrobił ...

 using System.DirectoryServices; 

     // Impersonate the Admin to Reset the Password/Unlock Account // 
     // Change variables below. 
     ImpersonateUser iu = new ImpersonateUser(); 
     if (iu.impersonateValidUser("AdminUserName", "DomainName", "AdminPassword")) 
     { 
      resetPassword("AdminUserName", "AdminPassword", UserToReset, "NewPassword"); 
      iu.undoImpersonation(); 
     } 

     // Perform the Reset/Unlock // 
     public void resetPassword(string username, string password, string acct, string newpassword) 
     { 
      string Path = // LDAP Connection String 
      string Username = username; 
      string Password = password; 
      string Domain = "DomainName\\"; // Change to your domain name 

      DirectoryEntry de = new DirectoryEntry(Path, Domain + Username, Password, AuthenticationTypes.Secure); 

      DirectorySearcher ds = new DirectorySearcher(de); 

      ds.Filter = "(&(objectClass=user)(|(sAMAccountName=" + acct + ")))"; 

      ds.PropertiesToLoad.Add("displayName"); 
      ds.PropertiesToLoad.Add("sAMAccountName"); 
      ds.PropertiesToLoad.Add("DistinguishedName"); 
      ds.PropertiesToLoad.Add("CN"); 

      SearchResult result = ds.FindOne(); 

      string dn = result.Properties["DistinguishedName"][0].ToString(); 

      DirectoryEntry uEntry = new DirectoryEntry("LDAP://" + dn, username, password); 

      uEntry.Invoke("SetPassword", new object[] { newpassword }); 
      uEntry.Properties["LockOutTime"].Value = 0; 
      uEntry.CommitChanges(); 
      uEntry.Close(); 
     } 

zdecydowanie zgadzają się, że może to prowadzić do problemów bezpieczeństwa, jeśli niewłaściwie wykorzystane, mamy wszelkie zmiany rejestrowane i wysłane do domeny adminów (więc ich w pętli) i automatycznie generujemy hasła. To była ogromna pomoc dla naszego małego działu IT, ponieważ administratorzy nie muszą już się budzić o 4 nad ranem, aby zresetować hasło.

+0

To jest dokładnie to, o czym mówię, zrobiłem program, który zostanie zainstalowany na maszynie do zarządzania roślinami, ale jest normalnym użytkownikiem programu, a my robimy to samo. Dodałem również daty do mojego programu, więc wszystko, co muszę zrobić, to ponownie opublikuj moją aplikację w katalogu, a kiedy kierownik zakładu otworzy moją aplikację, wyszuka aktualizacje, a następnie zaktualizuje, zmieniając przechowywane prawa administratora. –

+0

Otrzymuję ten błąd, gdy próbuję użyć Twojego przykładu i dodałem poprawne referencje ... Błąd Nie można znaleźć nazwy typu lub przestrzeni nazw "PersonersonateUser" (czy brakuje instrukcji użycia lub odniesienia do zespołu ?) \t im używanie dotnet 3.5 może to? –

+0

Kilka rzeczy ... 1.Jestem prawie pewien, że użytkownik inicjujący podszywanie się (konto ASPNET lub NETWORK SERVICES) musi mieć zestaw uprawnień "Ustaw jako część systemu operacyjnego". Minęło trochę czasu, więc sprawdź to ... 2. Powinienem był ci powiedzieć, że moje odniesienie do podszywanych użytkowników odnosi się do innej klasy, w której zamykam przetwarzanie impersate ... do ponownego użycia ... Zobacz ten projekt Code artykuł czegoś podobnego: http://www.codeproject.com/KB/cs/zetaimpersonator.aspx Jeśli nie wymyślisz tego, mogę opublikować pełne źródło pracy w poniedziałek ... Powodzenia! – Zachary

0

Ten kod pozwoli ci zadzwonić do innego pliku wykonywalnego i uruchomić go jako administrator.

try 
{ 
    path = path_to_your_executable; 

    ProcessStartInfo myProcess = new ProcessStartInfo(path); 
    myProcess.Domain = domain; 
    myProcess.UserName = username; 
    myProcess.Password = password; 
    myProcess.UseShellExecute = false; 

    Process.Start(myProcess); 
} 
catch (Exception myException) 
{ 
    // error handling 
} 

Nie dokładnie to, czego szukasz, ale jest to możliwe rozwiązanie.

+0

To może załatwić sprawę tak długo, jak będzie uwierzytelniać moją aplikację i daje jej uprawnienia administratora do odblokowania tego użytkownika. Pozwól mi to ułożyć lepiej. po pierwsze DZIĘKUJEMY TAK DUŻO DLA KAŻDEGO! Ograniczam to do przeszukiwania tylko określonej jednostki organizacyjnej, a przy tym jest to ogólne konto, które jak 10 osób używa do logowania się do 5 konsol dookoła zakładu, które czasem zepsuły i blokuje to ogólne konto, więc ochrona naprawdę się nie martwi. o ile większość baz jest objęta i to konto przechowywane w mojej aplikacji będzie monitorowane bardzo blisko i wiele się zmieniło. –

+0

lol tylko staram się uniknąć tych 3-godzinnych wezwań do tego prostego zadania –

2

Oto klasa używam do wykonywania personifikacji na stronie ASP.NET 2.0, w systemie Windows 2000.

Przykład użycia:

if (iu.impersonateValidUser("AdminUserName", "DomainName", "AdminPassword")) 
{    
    // Do Something Under Other Users Security Context 
    iu.undoImpersonation(); 
} 

To wszystko ... Kompletna klasa poniżej.

using System; 
using System.Runtime.InteropServices; 
using System.Security.Principal; 


public class ImpersonateUser 
{ 
    public const int LOGON32_LOGON_INTERACTIVE = 2; 
    public const int LOGON32_PROVIDER_DEFAULT = 0; 

    WindowsImpersonationContext impersonationContext; 

    [DllImport("advapi32.dll")] 
    public static extern int LogonUserA(String lpszUserName, 
     String lpszDomain, 
     String lpszPassword, 
     int dwLogonType, 
     int dwLogonProvider, 
     ref IntPtr phToken); 
    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern int DuplicateToken(IntPtr hToken, 
     int impersonationLevel, 
     ref IntPtr hNewToken); 

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern bool RevertToSelf(); 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    public static extern bool CloseHandle(IntPtr handle); 

    public bool impersonateValidUser(String userName, String domain, String password) 
    { 
     WindowsIdentity tempWindowsIdentity; 
     IntPtr token = IntPtr.Zero; 
     IntPtr tokenDuplicate = IntPtr.Zero; 

     if (RevertToSelf()) 
     { 
      if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 
       LOGON32_PROVIDER_DEFAULT, ref token) != 0) 
      { 
       if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
       { 
        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); 
        impersonationContext = tempWindowsIdentity.Impersonate(); 
        if (impersonationContext != null) 
        { 
         CloseHandle(token); 
         CloseHandle(tokenDuplicate); 
         return true; 
        } 
       } 
      } 
     } 
     if (token != IntPtr.Zero) 
      CloseHandle(token); 
     if (tokenDuplicate != IntPtr.Zero) 
      CloseHandle(tokenDuplicate); 
     return false; 
    } 

    public void undoImpersonation() 
    { 
     impersonationContext.Undo(); 
    } 
} 
+0

Niesamowite dziękuję! –

+0

Z jakiegoś powodu mój program odblokuje tylko użytkownika, który niedawno utworzyłem do testowania. Użytkownicy, którzy tam byli, jeśli zablokuję jedną z nich, a następnie uruchomię moją aplikację, wyświetli ich listę w comboboxie i kliknę na nich, a następnie kliknę przycisk odblokowania, który wykonuje pracę po debugowaniu i obejrzeniu go przez kod i foudn, że pierwsze konto, które utworzyłem, zostaje znalezione i wysyła informacje z powrotem do wyniku, ale inni użytkownicy nie uzyskują wyniku o wartości zerowej, co może być problemem? Dziękujemy za poświęcony czas –

+0

Czy położenie kont jest takie samo, może być konieczna zmiana ścieżki LDAP w celu wskazania właściwej lokalizacji. Domyślnie użytkownicy w systemie Windows są tworzeni w CN o nazwie "Użytkownicy". Zwykle przechowujemy naszych użytkowników w jednostce organizacyjnej o nazwie "Lokalizacje geograficzne". Jeśli instrukcja ścieżki nie wskazuje poprawnej lokalizacji, konta użytkowników nie zostaną znalezione. – Zachary

Powiązane problemy