2013-08-06 65 views
6

Từ đọc của tôi về mạo danh người dùng trên Windows, người ta nên sử dụng đúng loại đăng nhập LOGON32_LOGON_NEW_CREDENTIALS để mạo danh người dùng vào cơ sở dữ liệu. Sử dụng wrapper đẹp mạo danh của Matt Johnson (ban đầu được đăng here và sau đó đánh bóng lên here), tôi đã thử kiểm tra điều này - đây là toàn bộ chương trình của tôi ngoại trừ các hằng số xác định DOMAIN, USER, PWD và CONN_STRING cụ thể của tôi.Ma thuật Windows mạo danh với LOGON32_LOGON_NEW_CREDENTIALS là gì?

using System; 
using System.Data.SqlClient; 
using SimpleImpersonation; 

namespace ImpersonationDemo 
{ 
    class Program 
    { 
     private static SqlConnection _connection; 

     static void Main(string[] args) 
     { 
      using (Impersonation.LogonUser(
        DOMAIN, USER, PWD, LogonType.NewCredentials)) 
      { 
       GetOpenConnection(); 
       CheckDbCredentials(); 
       CloseConnection(); 
      } 
      Console.WriteLine("Press return to exit"); 
      Console.ReadLine(); 
     } 

     private static void CheckDbCredentials() 
     { 
      using (
       var command = new SqlCommand(
        "SELECT nt_user_name, SUSER_SNAME() " 
        +"FROM sys.dm_exec_sessions WHERE session_id = @@SPID", 
        _connection)) 
      { 
       using (SqlDataReader reader = command.ExecuteReader()) 
       { 
        while (reader.Read()) 
        { 
         Console.WriteLine("{0}, {1}", 
          reader.GetString(0), reader.GetString(1)); 
        } 
       } 
      } 
     } 


     private static void GetOpenConnection() 
     { 
      _connection = new SqlConnection(CONN_STRING); 
      _connection.Open(); 
     } 

     private static void CloseConnection() 
     { 
      _connection.Close(); 
     } 
    } 
} 

Nhưng điều đó không hiệu quả. Báo cáo đầu ra me (người dùng đăng nhập cơ bản của tôi) từ cả hai nt_user_nameSUSER_NAME(). (Và SQL Profiler báo cáo chính xác cùng một điều, truy vấn trong mã chỉ đơn giản là một cách thuận tiện để xem những gì SQL Profiler nói với tôi.)

Nếu tôi thay đổi từ LogonType.NewCredentials đến LogonType.Interactive (các enums có giá trị bạn mong đợi, được xác định trên pinvoke.net), sau đó nó hoạt động - mã trên báo cáo việc mạo danh DOMAIN và USER chính xác. Nhưng điều này cũng có nghĩa là phiên hiện tại đang bị mạo danh mà tôi không muốn - tôi chỉ muốn kết nối DB bị mạo danh.

tôi nghĩ rằng tôi tìm thấy một trục trặc ở trên - Johnson Mạo danh wrapper cứng mã nhà cung cấp đăng nhập như LOGON32_PROVIDER_DEFAULT, khi LogonUser API nêu rõ rằng các loại LOGON32_LOGON_NEW_CREDENTIALS đăng nhập chỉ được hỗ trợ bởi nhà cung cấp LOGON32_PROVIDER_WINNT50 đăng nhập. Vì vậy, tôi nắm lấy nguồn và thêm một tham số để cho phép xác định nhà cung cấp đăng nhập cần thiết ... nhưng điều đó không có sự khác biệt.

Vì vậy, tôi đang thiếu gì?

+0

Quay lại một bước từ vấn đề: Nếu bạn định đăng nhập vào cá thể máy chủ DB bằng cách sử dụng Bảo mật tích hợp, bạn không cần phải dựa vào mạo danh; trong trường hợp đó, ** 1. ** sử dụng đăng nhập SQL Server sẽ là tùy chọn dễ dàng hơn. Nếu bạn đang sử dụng Bảo mật tích hợp, ** 2. ** chỉ cho phép người dùng đích đăng nhập (nhưng hạn chế quyền của họ trên máy chủ và cơ sở dữ liệu càng nhiều càng tốt); hoặc (thậm chí tốt hơn :) ** 3. ** chỉ cho phép một dịch vụ truy cập cơ sở dữ liệu và chỉ cho phép ứng dụng của bạn truy cập dịch vụ, thực hiện xác thực và ủy quyền của riêng nó. – stakx

+1

Tôi đánh giá cao các đề xuất, @stakx; tuy nhiên, trong trường hợp này tôi không có sự linh hoạt để thực hiện những thay đổi kiến ​​trúc đó. Và bên cạnh đó, tôi có thể không bao giờ có thể có được một giấc ngủ đêm âm thanh một lần nữa cho đến khi tôi tìm hiểu lý do tại sao thất bại ở trên :-)! –

+0

Điều gì sẽ xảy ra nếu bạn sử dụng C để nhận mã thông báo LOGON32_LOGON_NEW_CREDENTIALS và sau đó khởi chạy một quy trình riêng biệt với mã thông báo để thực hiện công việc SQL thay cho bạn? (Quy trình mới có thể bằng C#.) –

Trả lời

5

Câu trả lời, tôi xấu hổ khi nói, đã ở ngay trước mặt tôi. Các trạng thái LogonUser API:

loại đăng nhập này cho phép người gọi để sao chép thẻ hiện tại của nó và xác định thông tin mới cho các kết nối ra bên ngoài. Phiên đăng nhập mới có cùng số nhận dạng địa phương nhưng sử dụng thông tin xác thực khác nhau cho các kết nối mạng khác. [tôi nhấn mạnh]

Nhưng cơ sở dữ liệu của tôi là trên cùng một máy như chương trình đang chạy của tôi vì vậy theo định nghĩa nó sẽ không hiển thị các thông tin mới! Tôi tin rằng sự mạo danh sẽ hoạt động chính xác với LOGON32_LOGON_NEW_CREDENTIALS khi tôi chuyển cơ sở dữ liệu của mình sang một hộp khác. Thở dài.