2009-05-27 54 views
6

Tôi đã viết một ứng dụng C# để mở khóa người dùng khi họ bị khóa tài khoản của họ (Active Directory). Ứng dụng tìm kiếm người dùng trong một OU cụ thể và sẽ liệt kê những người dùng bị khóa trong một ComboBox. Sau đó, bạn chọn người dùng đó từ ComboBox và chọn mở khóa.Làm thế nào để chạy ứng dụng C# với tín dụng quản trị?

Nếu bạn đăng nhập với tư cách quản trị viên, nó hoạt động hoàn hảo. Nếu bạn là người dùng bình thường thì không.

Tôi muốn chạy ứng dụng của mình với tín dụng quản trị nhưng dưới người dùng thông thường cũng an toàn nhất có thể.

Tôi đã đọc có thể lập trình dịch vụ cửa sổ nhưng tôi không rõ cách lập trình ứng dụng để cài đặt, chạy dưới dạng dịch vụ và chạy dưới quyền quản trị.

+0

Bạn có thể sử dụng Vista/W7/Server2008 và bạn đã đăng nhập với tư cách quản trị viên nhưng ứng dụng chạy w/out thông tin xác thực nâng cao? – Nate

+0

đây là tất cả các trạm làm việc chuyên nghiệp xp và AD là win2k3 –

Trả lời

1

Có vẻ như bạn muốn mạo danh người dùng quản trị.Đây là article and demo. Hình như được viết bằng .Net 1 nhưng sẽ giúp bạn bắt đầu. Ngoài ra, hãy xem lớp học WindowsIdentity.

+1

vấn đề với điều này là nó rất cũ và không được cập nhật. Mạo danh người dùng quản trị cho đến nay có nghĩa là thông tin đăng nhập cần phải vượt qua, điều này không lý tưởng vì họ cần bảo vệ. – IbrarMumtaz

8

Mục tiêu đằng sau ứng dụng này đánh tôi là sai. Về cơ bản, bạn đang cố gắng tạo một phương tiện cho phép người dùng không phải quản trị viên mở khóa các tài khoản ... đó là, vì lý do chính đáng, một tính năng không khả dụng đối với người dùng thông thường.

+2

Tôi đồng ý thường đó là một ý tưởng tồi; tuy nhiên, anh ta có thể cho phép một người sử dụng điện (đại diện hỗ trợ?) mở khóa các tài khoản người dùng khác bằng cách cấp toàn quyền quản trị. – Nate

+0

Không thể ủy quyền cụ thể đó cho nhóm thích hợp? – Rob

0

Bạn không thể sử dụng Dịch vụ Windows (dễ dàng), vì Dịch vụ Windows không thể có GUI. Cách duy nhất để làm điều này như một dịch vụ sẽ là cài đặt dịch vụ, và sau đó tạo một ứng dụng GUI sử dụng IPC để truyền đạt yêu cầu đến dịch vụ. Điều này sẽ mở ra một lỗ hổng tiềm năng, mặc dù.

Nếu bạn đang chạy trên Vista, một tùy chọn tốt sẽ là edit the manifest file và thêm requireAdministrator.


Edit:

Có vẻ như đề nghị đầu tiên của tôi có thể là những gì bạn muốn ... Để làm điều này, quá trình cơ bản là:

  • Hãy ứng dụng của bạn một dịch vụ cửa sổ. Có walkthrough of this process trên MSDN.
  • Làm cho dịch vụ của bạn phản hồi một số hình thức IPC. Bạn có thể sử dụng ổ cắm, đường ống hoặc bất kỳ hình thức giao tiếp nào khác. Dịch vụ sẽ "nghe" yêu cầu mở khóa người dùng, sau đó thực hiện việc này.
  • Cài đặt dịch vụ trên máy. Điều này sẽ làm cho nó chạy như một quản trị viên, và chỉ là luôn luôn trên.
  • Làm cho ứng dụng thứ hai hoạt động như một khách hàng. Sử dụng cùng một công nghệ IPC để giao tiếp với máy chủ. Thao tác này sẽ gửi yêu cầu mở khóa ứng dụng khách đến dịch vụ.

Sau đó, bạn có thể chạy ứng dụng khách như một người dùng bình thường (vì nó chỉ cần nói chuyện với dịch vụ, nó không làm bất cứ điều gì yêu cầu quyền).

+0

@Reed: Cái gọi là cách duy nhất để làm điều đó là những gì anh ta có thể (cho dù anh ta nhận ra hay không) muốn làm. Việc yêu cầu quản trị viên có thể dễ dàng thực hiện thông qua nhấp chuột phải, nhưng người dùng thông thường sẽ không thể chạy ứng dụng trong trường hợp đó. – Brian

+0

Vâng - Tôi đồng ý với bạn, tuy nhiên, điều này nói chung là một ý tưởng tồi ... –

+0

Tôi * đã * thực hiện việc này vài năm trở lại để sử dụng một API cổng COM nào đó sẽ chỉ hoạt động cho Người dùng điện và . Không đẹp, nhưng nó hoạt động. – crashmstr

2

Bạn không phải sử dụng dịch vụ cửa sổ để làm điều gì đó với tư cách người khác. Bạn có thể sử dụng mạo danh để đăng nhập với tư cách người dùng khác để thực hiện chuyển đổi thực tế. Dưới đây là một ví dụ tôi thấy rằng sử dụng Windows dll "advapi32.dll" để đăng nhập.

Lấy mã mẫu ra dưới cùng của trang. Tôi không muốn chỉ sao chép mã của anh ấy ở đây.

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

Một cavet với Mạo danh mặc dù là máy tính làm mạo danh cần phải được trên cùng một tên miền như là người dùng đó đang mạo danh của bạn.

0

Tôi có một tiện ích tương tự trên trang mạng nội bộ của mình, vì vậy các thành viên của bộ phận CNTT nằm trong các múi giờ khác nhau có thể xử lý đặt lại mật khẩu cũng thực hiện mở khóa tài khoản khi quản trị viên miền trên bờ biển phía tây không có sẵn. Đây là một nhiệm vụ khá đơn giản và đây là một ngoại trừ như thế nào tôi đã làm điều này ...

 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(); 
     } 

Tôi hoàn toàn đồng ý rằng điều này có thể dẫn đến các vấn đề bảo mật nếu sử dụng không đúng cách, chúng tôi đã từng thay đổi đăng nhập và gửi qua email cho tên miền quản trị viên (vì vậy họ trong vòng lặp) và chúng tôi tự động tạo mật khẩu. Điều này đã giúp ích rất nhiều cho bộ phận CNTT nhỏ của chúng tôi, vì quản trị viên không còn phải thức dậy lúc 4 giờ sáng để đặt lại mật khẩu.

+0

Đây chính xác là những gì tôi nói về việc tạo ra một prog sẽ được cài đặt trên máy quản lý nhà máy nhưng anh ấy là người dùng bình thường và chúng tôi cũng làm điều tương tự. tái xuất bản ứng dụng của tôi vào thư mục và khi nhà máy dẫn đầu mở ứng dụng của tôi, nó tìm kiếm các bản cập nhật, sau đó nó cập nhật, do đó thay đổi các ủy nhiệm quản trị được lưu trữ. –

+0

Im nhận được lỗi này khi cố gắng sử dụng ví dụ của bạn và tôi đã thêm tài liệu tham khảo chính xác ... Lỗi Không thể tìm thấy loại hoặc không gian tên 'ImpersonateUser' (bạn đang thiếu chỉ thị sử dụng hoặc tham chiếu assembly) ?) \t im sử dụng dotnet 3.5 có thể vậy? –

+0

Một vài điều ... 1.Tôi khá chắc chắn rằng người dùng bắt đầu mạo danh (tài khoản ASPNET hoặc NETWORK SERVICES) cần có bộ đặc quyền "Hành động như một phần của hệ điều hành". Tôi đã nói với bạn rằng người dùng mạo danh của tôi tham chiếu ở trên là một phần của lớp khác, nơi tôi kết thúc quá trình xử lý ... để sử dụng lại ... Hãy xem Dự án mã này bài viết của một cái gì đó tương tự: http://www.codeproject.com/KB/cs/zetaimpersonator.aspx Nếu bạn không tìm ra, tôi có thể đăng nguồn làm việc đầy đủ Thứ hai ... Chúc may mắn! – Zachary

0

Mã này sẽ cho phép bạn gọi một tệp thực thi khác và chạy nó là quản trị viên.

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 
} 

Không chính xác những gì bạn đang tìm nhưng đó là giải pháp khả thi.

+0

Điều này có thể làm các trick miễn là nó sẽ xác thực ứng dụng của tôi và cung cấp cho nó quyền admin để unlcok người dùng thats tất cả những gì maters. hãy để tôi làm điều này tốt hơn. trước hết, CẢM ƠN QUÝ VỊ MỌI MỌI NGƯỜI! Tôi giới hạn điều này để chỉ tìm kiếm một OU cụ thể và trong đó ou là tài khoản chung giống như 10 người sử dụng để đăng nhập vào 5 bàn giao tiếp xung quanh nhà máy mà đôi khi chúng vít lên và khóa tài khoản chung đó để an ninh thực sự không lo lắng bout tôi có hầu hết các căn cứ được bảo hiểm và tài khoản được lưu trữ trong ứng dụng của tôi sẽ được theo dõi rất gần và tín hiệu thay đổi rất nhiều. –

+0

lol chỉ cố gắng tránh những cuộc gọi 3 giờ sáng cho nhiệm vụ đơn giản này –

2

Đây là lớp tôi sử dụng để thực hiện mạo danh trên một trang web ASP.NET 2.0, chạy trên Windows 2000.

Ví dụ Cách sử dụng:

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

Vậy đó ... Toàn bộ lớp bên dưới.

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

Tuyệt vời cảm ơn bạn! –

+0

Vì lý do nào đó, chương trình của tôi sẽ chỉ mở khóa người dùng mà tôi đã tạo gần đây để thử nghiệm. Những người dùng đã ở trong đó nếu tôi khóa một trong số họ ra và sau đó chạy ứng dụng của tôi nó sẽ liệt kê chúng trong combobox và tôi bấm vào chúng và sau đó nhấp vào nút mở khóa nó dosnt làm việc sau khi gỡ lỗi và xem nó đi qua mã i foudn rằng rstest tài khoản tôi tạo được tìm thấy và gửi thông tin trở lại kết quả nhưng những người dùng khác không có kết quả vẫn null những gì có thể là vấn đề? Cảm ơn bạn đã dành thời gian –

+0

Vị trí của các tài khoản giống nhau, bạn có thể cần thay đổi LDAP PATH để trỏ đến vị trí chính xác. Theo mặc định, người dùng trong Windows được tạo trong CN được gọi là "Người dùng". Chúng tôi thường lưu trữ người dùng của mình trong OU được gọi là "Vị trí địa lý". Nếu tuyên bố đường dẫn không trỏ đến vị trí chính xác, tài khoản người dùng sẽ không được tìm thấy. – Zachary

Các vấn đề liên quan