2015-01-08 11 views
6

Vì mục đích học tập Tôi đang viết ứng dụng Active Directory của riêng mình. Để thực hiện các lệnh như mở khóa tài khoản và đặt lại mật khẩu, tôi phải đặt vào tài khoản quản trị và mật khẩu của mình và sử dụng và WindowsIdentity.Impersonate chạy mã làm tài khoản quản trị của tôi. Tôi tự hỏi về các tùy chọn để bảo mật mật khẩu của mình, vì nó phải được sử dụng nhiều lần trong chương trình của tôi.Sử dụng SecureString với LogonUser

Từ những gì tôi hiểu, tôi có thể sử dụng SecureString để lưu trữ mật khẩu. Nhưng để chạy mã như tài khoản quản trị của tôi, tôi đã sử dụng WindowsIdentity.Impersonate và để sử dụng tôi phải nhận mã thông báo từ LogonUser yêu cầu một số string thông thường và không phải SecureString.

Vì vậy, tôi sẽ phải:

  1. Đăng lúc khởi động

  2. Chuyển đổi đầu vào cho một SecureString

  3. Xóa đầu vào

Sau đó, sau khi tôi muốn tạo thành một hàm đòi hỏi độ cao:

  1. Chuyển đổi trước đó tạo SecureString để string

  2. Vượt qua chuỗi chuyển đổi để LogonUser

  3. Xóa chuỗi chuyển đổi để null

  4. Execute lệnh

  5. C lear các đối tượng LogonUser

Đây có phải là cách chính xác để tiếp cận vấn đề này không? Có vẻ lạ khi phải chuyển đổi SecureString thành string để sử dụng nó ... có vẻ như nó sẽ đánh bại mục đích và để lại mật khẩu dễ bị tổn thương hơn trong khi tôi đang chuyển đổi nó.

EDIT: Cố định tên cho LogonUser

+1

Bạn đúng là việc chuyển đổi thành chuỗi sẽ đánh bại mục đích. UserImpersonation là gì? Liệu nó PInvoke đến một API Win32? Bạn có thể phải thay đổi hàm mà nó sử dụng để chuyển vào IntPtr thay vì chuỗi. –

+0

Rất tiếc xin lỗi ... Tôi sẽ sửa câu hỏi của tôi. Vâng, 'UserImpersonation' là một lớp tôi đã viết một thời gian dài trước đây ... về cơ bản nó là một trình bao bọc cho [LogonUser] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184%28v= vs.85% 29.aspx), cũng yêu cầu một chuỗi mật khẩu. Có thể thay đổi thành 'IntPtr' được không? Nếu đúng như vậy, tôi có thể chuyển một tham số 'SecureString' tới tham số mật khẩu thay thế không?(Tôi sẽ thử ngay bây giờ nhưng tôi không còn ở nơi làm việc nữa ...) – duckwizzle

+1

Không, bạn không thể sử dụng trực tiếp 'SecureString' nhưng không nên chuyển mật khẩu một cách an toàn. Tôi sẽ trả lời dưới đây ... –

Trả lời

5

Trong lớp UserImpersonation của bạn, thay đổi cách bạn khai báo LogonUser sử dụng IntPtr thay vì string cho mật khẩu.

Mẫu mã cho Marshal.SecureStringToGlobalAllocUnicode có chính xác những gì bạn cần. Dưới đây là đoạn mã có liên quan:

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
internal static extern bool LogonUser(String username, String domain, 
             IntPtr password, int logonType, 
             int logonProvider, ref IntPtr token); 

... 

IntPtr tokenHandle = IntPtr.Zero; 

IntPtr passwordPtr = IntPtr.Zero; 

try 
{ 
    // Marshal the SecureString to unmanaged memory. 
    passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password); 

    returnValue = LogonUser(userName, domainName, passwordPtr, 
          LOGON32_LOGON_INTERACTIVE, 
          LOGON32_PROVIDER_DEFAULT, ref tokenHandle); 

} 
finally 
{ 
    // Zero-out and free the unmanaged string reference. 
    Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr); 

    // Close the token handle. 
    CloseHandle(tokenHandle); 
} 
+0

Hoàn hảo! Cảm ơn bạn! :) – duckwizzle

+0

@duckwizzle Không phải lo lắng –

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