zoukankan      html  css  js  c++  java
  • .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>
  • 相关阅读:
    Hihocoder 1275 扫地机器人 计算几何
    CodeForces 771C Bear and Tree Jumps 树形DP
    CodeForces 778D Parquet Re-laying 构造
    CodeForces 785E Anton and Permutation 分块
    CodeForces 785D Anton and School
    CodeForces 785C Anton and Fairy Tale 二分
    Hexo Next 接入 google AdSense 广告
    如何统计 Hexo 网站的访问地区和IP
    Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple Task Points
    通过ODBC接口访问人大金仓数据库
  • 原文地址:https://www.cnblogs.com/neozhu/p/277177.html
Copyright © 2011-2022 走看看