سؤال

هناك مجموعة بسيطة من خارج منطقة الجزاء طريقة انتحال شخصية المستخدم .الشبكة ؟

حتى الآن لقد تم استخدام هذه الفئة من رمز المشروع كل ما عندي من الانتحال المتطلبات.

هل هناك طريقة أفضل للقيام بذلك باستخدام .NET Framework ؟

لدي المستخدم الاعتماد مجموعة (اسم المستخدم, كلمة المرور, اسم المجال) الذي يمثل الهوية أحتاج إلى انتحال شخصية.

هل كانت مفيدة؟

المحلول

هنا بعض جيدة عامة .صافي التمثيل المفاهيم.

في الأساس سوف تكون الاستفادة من هذه الفئات التي هي من خارج منطقة الجزاء في .NET framework:

رمز يمكن غالبا ما تحصل طويلة على الرغم من أنه هو السبب في أننا نرى العديد من الأمثلة مثل واحد كنت المرجعية التي تحاول تبسيط العملية.

نصائح أخرى

"الانتحال" في .صافي المساحة عموما يعني تشغيل التعليمات البرمجية تحت حساب مستخدم محدد.بل هو نوعا ما منفصلة مفهوم من الحصول على الوصول إلى حساب المستخدم عن طريق اسم المستخدم وكلمة المرور, على الرغم من أن هذين الأفكار الزوج معا في كثير من الأحيان.سأذكر لهم على حد سواء ، ومن ثم شرح كيفية استخدام بلدي SimpleImpersonation المكتبة التي يستخدمها داخليا.

الانتحال

واجهات برمجة التطبيقات عن الانتحال في .صافي عبر System.Security.Principal مساحة:

  • أحدث رمز (.صافي 4.6+, .صافي الأساسية ، إلخ.) ينبغي أن تستخدم عموما WindowsIdentity.RunImpersonated, الذي يقبل مؤشر إلى الرمز المميز للمستخدم الحساب ثم إما Action أو Func<T> من أجل تنفيذ الشفرة.

    WindowsIdentity.RunImpersonated(tokenHandle, () =>
    {
        // do whatever you want as this user.
    });
    

    أو

    var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
    {
        // do whatever you want as this user.
        return result;
    });
    
  • أقدم رمز يستخدم WindowsIdentity.Impersonate طريقة لاسترداد WindowsImpersonationContext الكائن.هذا الكائن تنفذ IDisposable, لذا عموما ينبغي أن يسمى من using كتلة.

    using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
    {
        // do whatever you want as this user.
    }
    

    في حين أن هذا المعهد لا يزال موجودا في .NET Framework ، عموما يجب تجنبها, و هو غير متوفر في .صافي الأساسية أو .صافي القياسية.

الوصول إلى حساب المستخدم

API باستخدام اسم المستخدم وكلمة المرور للوصول إلى حساب المستخدم في ويندوز LogonUser - وهو Win32 API الأصلي.ليس هناك حاليا المدمج في .NET API من أجل الدعوة ، لذا لا بد من اللجوء إلى P/الاحتجاج.

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

هذا هو الأساسية استدعاء التعريف ، ومع ذلك هناك الكثير للنظر في الواقع استخدامه في الإنتاج:

  • الحصول على التعامل مع "آمنة" نمط الوصول.
  • إغلاق الأصلية يعالج بشكل مناسب
  • أمان الوصول إلى التعليمات البرمجية (CAS) مستويات الثقة (في .صافي الإطار فقط)
  • يمر SecureString عندما يمكنك جمع واحد بأمان عن طريق المستخدم المفاتيح.

كمية من التعليمات البرمجية إلى الكتابة لتوضيح كل هذا هو أبعد ما ينبغي أن يكون في ستاكوفيرفلوو الجواب ، IMHO.

جنبا إلى جنب وأسهل النهج

بدلا من كتابة كل هذا بنفسك, النظر في استخدام بلدي SimpleImpersonation مكتبة, الذي يجمع بين التمثيل المستخدم الوصول إلى API واحد.أنه يعمل بشكل جيد في كل الحديثة و القديمة مدونة قواعد مع نفس API بسيطة:

var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
}); 

أو

var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
    return something;
});

لاحظ أنه مشابه جدا WindowsIdentity.RunImpersonated API, ولكن لا تتطلب تعرف أي شيء عن رمزية مقابض.

هذا هو API اعتبارا من الإصدار 3.0.0.رؤية المشروع التمهيدي للحصول على مزيد من التفاصيل.نلاحظ أيضا أن النسخة السابقة من المكتبة تستخدم API مع IDisposable نمط مماثلة WindowsIdentity.Impersonate.الإصدار الأحدث هو أكثر أمانا, و كلاهما لا تزال تستخدم داخليا.

وربما هذا هو ما تريد:

using System.Security.Principal;
using(WindowsIdentity.GetCurrent().Impersonate())
{
     //your code goes here
}

ولكن أنا حقا بحاجة إلى المزيد من التفاصيل لمساعدتك على الخروج.هل يمكن أن تفعل التمثيل مع ملف التكوين (إذا كنت تحاول القيام بذلك على الموقع) أو من خلال طريقة الديكور (منها) إذا كانت خدمة WCF, أو من خلال...يمكنك الحصول على هذه الفكرة.

أيضا, إذا كنا نتحدث عن انتحال شخصية عميل يسمى خدمة معينة (أو تطبيق ويب), تحتاج إلى تكوين العميل بشكل صحيح بحيث يمر المناسبة المميزة.

وأخيرا ، إذا ما كنت حقا تريد القيام به هو وفد تحتاج أيضا إلى إعداد الإعلان بشكل صحيح بحيث يمكن للمستخدمين و آلات موثوق للتفويض.

تحرير:
نلقي نظرة هنا لمعرفة كيفية انتحال شخصية مستخدم آخر, و المزيد من الوثائق.

هنا هو بلدي vb.net ميناء مات جونسون الإجابة.انا وأضاف التعداد من أجل تسجيل الدخول أنواع. LOGON32_LOGON_INTERACTIVE كان أول تعداد القيمة التي يعمل sql server.بلدي سلسلة الاتصال كان مجرد الوثوق بها.لا اسم المستخدم / كلمة المرور في سلسلة الاتصال.

  <PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
  Public Class Impersonation
    Implements IDisposable

    Public Enum LogonTypes
      ''' <summary>
      ''' This logon type is intended for users who will be interactively using the computer, such as a user being logged on  
      ''' by a terminal server, remote shell, or similar process.
      ''' This logon type has the additional expense of caching logon information for disconnected operations; 
      ''' therefore, it is inappropriate for some client/server applications,
      ''' such as a mail server.
      ''' </summary>
      LOGON32_LOGON_INTERACTIVE = 2

      ''' <summary>
      ''' This logon type is intended for high performance servers to authenticate plaintext passwords.
      ''' The LogonUser function does not cache credentials for this logon type.
      ''' </summary>
      LOGON32_LOGON_NETWORK = 3

      ''' <summary>
      ''' This logon type is intended for batch servers, where processes may be executing on behalf of a user without 
      ''' their direct intervention. This type is also for higher performance servers that process many plaintext
      ''' authentication attempts at a time, such as mail or Web servers. 
      ''' The LogonUser function does not cache credentials for this logon type.
      ''' </summary>
      LOGON32_LOGON_BATCH = 4

      ''' <summary>
      ''' Indicates a service-type logon. The account provided must have the service privilege enabled. 
      ''' </summary>
      LOGON32_LOGON_SERVICE = 5

      ''' <summary>
      ''' This logon type is for GINA DLLs that log on users who will be interactively using the computer. 
      ''' This logon type can generate a unique audit record that shows when the workstation was unlocked. 
      ''' </summary>
      LOGON32_LOGON_UNLOCK = 7

      ''' <summary>
      ''' This logon type preserves the name and password in the authentication package, which allows the server to make 
      ''' connections to other network servers while impersonating the client. A server can accept plaintext credentials 
      ''' from a client, call LogonUser, verify that the user can access the system across the network, and still 
      ''' communicate with other servers.
      ''' NOTE: Windows NT:  This value is not supported. 
      ''' </summary>
      LOGON32_LOGON_NETWORK_CLEARTEXT = 8

      ''' <summary>
      ''' This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
      ''' The new logon session has the same local identifier but uses different credentials for other network connections. 
      ''' NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
      ''' NOTE: Windows NT:  This value is not supported. 
      ''' </summary>
      LOGON32_LOGON_NEW_CREDENTIALS = 9
    End Enum

    <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Shared Function LogonUser(lpszUsername As [String], lpszDomain As [String], lpszPassword As [String], dwLogonType As Integer, dwLogonProvider As Integer, ByRef phToken As SafeTokenHandle) As Boolean
    End Function

    Public Sub New(Domain As String, UserName As String, Password As String, Optional LogonType As LogonTypes = LogonTypes.LOGON32_LOGON_INTERACTIVE)
      Dim ok = LogonUser(UserName, Domain, Password, LogonType, 0, _SafeTokenHandle)
      If Not ok Then
        Dim errorCode = Marshal.GetLastWin32Error()
        Throw New ApplicationException(String.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode))
      End If

      WindowsImpersonationContext = WindowsIdentity.Impersonate(_SafeTokenHandle.DangerousGetHandle())
    End Sub

    Private ReadOnly _SafeTokenHandle As New SafeTokenHandle
    Private ReadOnly WindowsImpersonationContext As WindowsImpersonationContext

    Public Sub Dispose() Implements System.IDisposable.Dispose
      Me.WindowsImpersonationContext.Dispose()
      Me._SafeTokenHandle.Dispose()
    End Sub

    Public NotInheritable Class SafeTokenHandle
      Inherits SafeHandleZeroOrMinusOneIsInvalid

      <DllImport("kernel32.dll")> _
      <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)> _
      <SuppressUnmanagedCodeSecurity()> _
      Private Shared Function CloseHandle(handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
      End Function

      Public Sub New()
        MyBase.New(True)
      End Sub

      Protected Overrides Function ReleaseHandle() As Boolean
        Return CloseHandle(handle)
      End Function
    End Class

  End Class

تحتاج إلى استخدام مع Using بيان أن تحتوي على بعض التعليمات البرمجية لتشغيل انتحاله.

عرض المزيد من التفاصيل من إجابتي السابقة خلقت مجموعة nuget Nuget

رمز على جيثب

العينة :يمكنك استخدام :

           string login = "";
           string domain = "";
           string password = "";

           using (UserImpersonation user = new UserImpersonation(login, domain, password))
           {
               if (user.ImpersonateValidUser())
               {
                   File.WriteAllText("test.txt", "your text");
                   Console.WriteLine("File writed");
               }
               else
               {
                   Console.WriteLine("User not connected");
               }
           }

Vieuw كامل رمز :

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


/// <summary>
/// Object to change the user authticated
/// </summary>
public class UserImpersonation : IDisposable
{
    /// <summary>
    /// Logon method (check athetification) from advapi32.dll
    /// </summary>
    /// <param name="lpszUserName"></param>
    /// <param name="lpszDomain"></param>
    /// <param name="lpszPassword"></param>
    /// <param name="dwLogonType"></param>
    /// <param name="dwLogonProvider"></param>
    /// <param name="phToken"></param>
    /// <returns></returns>
    [DllImport("advapi32.dll")]
    private static extern bool LogonUser(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);

    /// <summary>
    /// Close
    /// </summary>
    /// <param name="handle"></param>
    /// <returns></returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern bool CloseHandle(IntPtr handle);

    private WindowsImpersonationContext _windowsImpersonationContext;
    private IntPtr _tokenHandle;
    private string _userName;
    private string _domain;
    private string _passWord;

    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;

    /// <summary>
    /// Initialize a UserImpersonation
    /// </summary>
    /// <param name="userName"></param>
    /// <param name="domain"></param>
    /// <param name="passWord"></param>
    public UserImpersonation(string userName, string domain, string passWord)
    {
        _userName = userName;
        _domain = domain;
        _passWord = passWord;
    }

    /// <summary>
    /// Valiate the user inforamtion
    /// </summary>
    /// <returns></returns>
    public bool ImpersonateValidUser()
    {
        bool returnValue = LogonUser(_userName, _domain, _passWord,
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                ref _tokenHandle);

        if (false == returnValue)
        {
            return false;
        }

        WindowsIdentity newId = new WindowsIdentity(_tokenHandle);
        _windowsImpersonationContext = newId.Impersonate();
        return true;
    }

    #region IDisposable Members

    /// <summary>
    /// Dispose the UserImpersonation connection
    /// </summary>
    public void Dispose()
    {
        if (_windowsImpersonationContext != null)
            _windowsImpersonationContext.Undo();
        if (_tokenHandle != IntPtr.Zero)
            CloseHandle(_tokenHandle);
    }

    #endregion
}

أنا على علم أنني في وقت متأخر جدا بالنسبة للحزب ، ولكن أنا أعتبر أن المكتبة من فيليب ألان-هاردينغ, إنه أفضل واحد ل هذه الحالة وما شابهها.

تحتاج فقط قطعة صغيرة من التعليمات البرمجية مثل هذا واحد:

private const string LOGIN = "mamy";
private const string DOMAIN = "mongo";
private const string PASSWORD = "HelloMongo2017";

private void DBConnection()
{
    using (Impersonator user = new Impersonator(LOGIN, DOMAIN, PASSWORD, LogonType.LOGON32_LOGON_NEW_CREDENTIALS, LogonProvider.LOGON32_PROVIDER_WINNT50))
    {
    }
}

وإضافة صفه:

.NET (C#) الانتحال مع بيانات اعتماد الشبكة

بلدي على سبيل المثال يمكن أن تستخدم إذا كنت تحتاج إلى الممثل تسجيل الدخول إلى بيانات اعتماد الشبكة ، ولكن لديه المزيد من الخيارات.

يمكنك استخدام هذا الحل.(استخدام حزمة nuget) شفرة المصدر متاحة على :جيثب:https://github.com/michelcedric/UserImpersonation

مزيد من التفاصيل https://michelcedric.wordpress.com/2015/09/03/usurpation-didentite-dun-user-c-user-impersonation/

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top