• .net下模拟不同身份登陆以获取不同权限


      1.net下模拟不同身份登陆以获取不同权限  
      2 
      3作者:佚名 时间:2004-04-16 09:14 出处:互连网 责编:chinaitpower  
      4 
      5              摘要:.net下模拟不同身份登陆以获取不同权限 
      6 
      7 
      8不管是asp.net、web service还是window service,程序运行的时候只有本地计算机的部分权限,有时候需要更大的权限,比如读写某台服务器或域中的一台计算机上的文件等,这就需要更大的权限,比如域帐户权限。 
      9
     10通过获取不同身份的WindowsImpersonationContext对象,可以模拟不同用户登陆,请看我生成的NetworkSecurity类的 
     11public static WindowsImpersonationContext ImpersonateUser(string strDomain, 
     12string strLogin, 
     13
     14string strPwd, 
     15
     16LogonType logonType, 
     17
     18LogonProvider logonProvider); 
     19
     20附NetworkSecurity.cs源代码如下: 
     21
     22/* 
     23* Author : TongWei 
     24* Date : 2005-1-25 
     25* Rights : China Netwave Inc.@2005 
     26*/
     
     27
     28using System; 
     29using System.Runtime.InteropServices; 
     30using System.Security.Principal; 
     31using System.Security.Permissions; 
     32
     33namespace CNW.OMP.Common.Utility 
     34
     35public enum LogonType : int 
     36
     37/// <summary> 
     38/// This logon type is intended for users who will be interactively using the computer, such as a user 
     39/// being logged on by a terminal server, remote shell, or similar process. This logon type has the 
     40/// additional expense of caching logon information for disconnected operation, and is therefore 
     41/// inappropriate for some client/server applications, such as a mail server. 
     42/// </summary> 

     43LOGON32_LOGON_INTERACTIVE = 2
     44
     45/// <summary> 
     46/// This logon type is intended for high performance servers to authenticate clear text passwords. 
     47/// The LogonUser function does not cache credentials for this logon type. 
     48/// </summary> 

     49LOGON32_LOGON_NETWORK = 3
     50
     51/// <summary> 
     52/// This logon type is intended for batch servers, where processes may be executing on behalf of a user 
     53/// without their direct intervention; or for higher performance servers that process many clear-text 
     54/// authentication attempts at a time, such as mail or web servers. The LogonUser function does not cache 
     55/// credentials for this logon type. 
     56/// </summary> 

     57LOGON32_LOGON_BATCH = 4
     58
     59/// <summary> 
     60/// Indicates a service-type logon. The account provided must have the service privilege enabled. 
     61/// </summary> 

     62LOGON32_LOGON_SERVICE = 5
     63
     64/// <summary> 
     65/// This logon type is intended for GINA DLLs logging on users who will be interactively using the computer. 
     66/// This logon type allows a unique audit record to be generated that shows when the workstation was unlocked. 
     67/// </summary> 

     68LOGON32_LOGON_UNLOCK = 7
     69
     70/// <summary> 
     71/// Windows XP/2000: This logon type preserves the name and password in the authentication packages, 
     72/// allowing the server to make connections to other network servers while impersonating the client. 
     73/// This allows a server to accept clear text credentials from a client, call LogonUser, verify that 
     74/// the user can access the system across the network, and still communicate with other servers. 
     75/// </summary> 

     76LOGON32_LOGON_NETWORK_CLEARTEXT = 8
     77
     78/// <summary> 
     79/// Windows XP/2000: This logon type allows the caller to clone its current token and specify new credentials 
     80/// for outbound connections. The new logon session has the same local identity, but uses different credentials 
     81/// for other network connections. 
     82/// This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider. 
     83/// </summary> 

     84LOGON32_LOGON_NEW_CREDENTIALS = 9 
     85}

     86
     87public enum LogonProvider : int 
     88
     89/// <summary> 
     90/// Use the standard logon provider for the system. The default security provider is NTLM. 
     91/// Windows XP: The default provider is negotiate, unless you pass NULL for the domain name and 
     92/// the user name is not in UPN format. In this case the default provider is NTLM. 
     93/// </summary> 

     94LOGON32_PROVIDER_DEFAULT = 0
     95
     96/// <summary> 
     97/// Use the Windows NT 3.5 logon provider. 
     98/// </summary> 

     99LOGON32_PROVIDER_WINNT35 = 1
    100
    101/// <summary> 
    102/// Use the NTLM logon provider. 
    103/// </summary> 

    104LOGON32_PROVIDER_WINNT40 = 2
    105
    106/// <summary> 
    107/// Windows XP/2000: Use the negotiate logon provider. 
    108/// </summary> 

    109LOGON32_PROVIDER_WINNT50 = 3 
    110}

    111
    112class SecuUtil32 
    113
    114[DllImport("advapi32.dll", SetLastError=true)] 
    115public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, 
    116int dwLogonType, int dwLogonProvider, ref IntPtr TokenHandle); 
    117
    118[DllImport("kernel32.dll", CharSet=CharSet.Auto)] 
    119public extern static bool CloseHandle(IntPtr handle); 
    120
    121[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] 
    122public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, 
    123int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle); 
    124}
     
    125
    126public class NetworkSecurity 
    127
    128public NetworkSecurity() 
    129
    130// 
    131// TODO: Add constructor logic here 
    132// 
    133}
     
    134
    135/// <summary> 
    136/// The ImpersonateUser function attempts to log a user on to the local computer. 
    137/// The local computer is the computer from which ImpersonateUser was called. 
    138/// You cannot use ImpersonateUser to log on to a remote computer. 
    139/// You specify the user with a user name and domain, and authenticate the user with a clear-text password. 
    140/// If the function succeeds, you receive a handle to a token that represents the logged-on user. 
    141/// You can then use this token handle to impersonate the specified user, or in most cases, 
    142/// to create a process running in the context of the specified user. 
    143/// </summary> 
    144/// <param name="strDomain"> 
    145/// specifies the name of the domain or server whose account database contains the strLogin account. 
    146/// </param> 
    147/// <param name="strLogin">specifies the name of the user.</param> 
    148/// <param name="strPwd">specifies the clear-text password for the user account specified by strLogin.</param> 
    149/// <param name="logonType">Specifies the type of logon operation to perform.</param> 
    150/// <param name="logonProvider">Specifies the logon provider.</param> 
    151/// <example> 
    152/// //Add System.Security.dll 
    153/// //using System.Security.Principal; 
    154/// 
    155/// string strDomain=ConfigurationSettings.AppSettings["mSALoginDomainName"]; 
    156/// string strUser=ConfigurationSettings.AppSettings["mSALoginDomainUser"]; 
    157/// string strPassword=ConfigurationSettings.AppSettings["mSALoginDomainPassword"]; 
    158/// 
    159/// WindowsImpersonationContext impContext = null; 
    160/// try 
    161/// { 
    162/// impContext = NetworkSecurity.ImpersonateUser(strDomain,strUser,strPassword, 
    163/// LogonType.LOGON32_LOGON_SERVICE, 
    164/// LogonProvider.LOGON32_PROVIDER_DEFAULT); 
    165/// } 
    166/// catch 
    167/// { 
    168/// 
    169/// } 
    170/// 
    171/// //work under this logined user 
    172/// 
    173/// impContext.Undo(); 
    174/// </example> 
    175/// <returns> 
    176/// </returns> 

    177public static WindowsImpersonationContext ImpersonateUser(string strDomain, 
    178string strLogin, 
    179string strPwd, 
    180LogonType logonType, 
    181LogonProvider logonProvider) 
    182
    183// Initialize tokens 
    184IntPtr tokenHandle = new IntPtr(0); 
    185IntPtr dupeTokenHandle = new IntPtr(0); 
    186tokenHandle = IntPtr.Zero; 
    187dupeTokenHandle = IntPtr.Zero; 
    188
    189// If domain name was blank, assume local machine 
    190if (strDomain == ""
    191strDomain = System.Environment.MachineName; 
    192
    193try 
    194
    195const int SecurityImpersonation = 2
    196
    197// Call LogonUser to obtain a handle to an access token. 
    198bool returnValue = SecuUtil32.LogonUser( 
    199strLogin, 
    200strDomain, 
    201strPwd, 
    202(int)logonType, 
    203(int)logonProvider, 
    204ref tokenHandle); 
    205
    206// Did impersonation fail? 
    207if (false == returnValue) 
    208
    209int ret = Marshal.GetLastWin32Error(); 
    210// Throw the exception show the reason why LogonUser failed 
    211string strErr = String.Format("LogonUser failed with error code : {0}", ret); 
    212throw new ApplicationException(strErr, null); 
    213}
     
    214
    215// Get identity before impersonation 
    216bool retVal = SecuUtil32.DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle); 
    217
    218// Did DuplicateToken fail? 
    219if (false == retVal) 
    220
    221// Close existing handle 
    222SecuUtil32.CloseHandle(tokenHandle); 
    223// Throw the exception show the reason why DuplicateToken failed 
    224throw new ApplicationException("Failed to duplicate token"null); 
    225}
     
    226
    227// Create new identity using new primary token 
    228// The token that is passed to the following constructor must 
    229// be a primary token in order to use it for impersonation. 
    230WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle); 
    231WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 
    232
    233return impersonatedUser; 
    234}
     
    235catch (Exception ex) 
    236
    237throw new ApplicationException(ex.Message, ex); 
    238}
     
    239finally 
    240
    241// Close handle 
    242if (tokenHandle != IntPtr.Zero) 
    243SecuUtil32.CloseHandle(tokenHandle); 
    244if (dupeTokenHandle != IntPtr.Zero) 
    245SecuUtil32.CloseHandle(dupeTokenHandle); 
    246}
     
    247}
     
    248}
     
    249}
     
    250 
    251 
    252

    <%@ Page Language="C#"%>
    <%@ Import Namespace = "System.Web" %>
    <%@ Import Namespace = "System.Web.Security" %>
    <%@ Import Namespace = "System.Security.Principal" %>
    <%@ Import Namespace = "System.Runtime.InteropServices" %>

    <script runat=server>
    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 void Page_Load(Object s, EventArgs e)
    {
        
    if(impersonateValidUser("username""domain""password"))
        
    {
            
    //Insert your code that runs under the security context of a specific user here.
            undoImpersonation();
        }

        
    else
        
    {
            
    //Your impersonation failed. Therefore, include a fail-safe mechanism here.
        }

    }


    private 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, 2ref 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;
    }


    private void undoImpersonation()
    {
        impersonationContext.Undo();
    }

    </script>
  • 相关阅读:
    深度学习优化方法比较
    调参
    Numpy/Pytorch之数据类型与强制转换
    numpy:维度问题
    js模板引擎-juicer
    js模板引擎-腾讯artTemplate 简洁语法例子
    canva绘制时钟
    js中的break ,continue, return
    JavaScript奇技淫巧44招
    数据类型
  • 原文地址:https://www.cnblogs.com/neozhu/p/277177.html
Copyright © 2020-2023  润新知