首页 > 编程 > .NET > 正文

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

2024-07-10 12:58:41
字体:
来源:转载
供稿:网友
不管是asp.net、web service还是window service,程序运行的时候只有本地计算机的部分权限,有时候需要更大的权限,比如读写某台服务器或域中的一台计算机上的文件等,这就需要更大的权限,比如域帐户权限。

通过获取不同身份的windowsimpersonationcontext对象,可以模拟不同用户登陆,请看我生成的networksecurity类的
public static windowsimpersonationcontext impersonateuser(string strdomain,
string strlogin,

string strpwd,

logontype logontype,

logonprovider logonprovider);

附networksecurity.cs源代码如下:

/*
* author : tongwei
* date : 2005-1-25
* rights : china netwave [email protected]
*/

using system;
using system.runtime.interopservices;
using system.security.principal;
using system.security.permissions;

namespace cnw.omp.common.utility
{
public enum logontype : int
{
/// <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 operation, and is therefore
/// 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 clear text 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; or for higher performance servers that process many clear-text
/// 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 intended for gina dlls logging on users who will be interactively using the computer.
/// this logon type allows a unique audit record to be generated that shows when the workstation was unlocked.
/// </summary>
logon32_logon_unlock = 7,

/// <summary>
/// windows xp/2000: this logon type preserves the name and password in the authentication packages,
/// allowing the server to make connections to other network servers while impersonating the client.
/// this allows a server to accept clear text credentials from a client, call logonuser, verify that
/// the user can access the system across the network, and still communicate with other servers.
/// </summary>
logon32_logon_network_cleartext = 8,

/// <summary>
/// windows xp/2000: 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 identity, but uses different credentials
/// for other network connections.
/// this logon type is supported only by the logon32_provider_winnt50 logon provider.
/// </summary>
logon32_logon_new_credentials = 9
};

public enum logonprovider : int
{
/// <summary>
/// use the standard logon provider for the system. the default security provider is ntlm.
/// windows xp: the default provider is negotiate, unless you pass null for the domain name and
/// the user name is not in upn format. in this case the default provider is ntlm.
/// </summary>
logon32_provider_default = 0,

/// <summary>
/// use the windows nt 3.5 logon provider.
/// </summary>
logon32_provider_winnt35 = 1,

/// <summary>
/// use the ntlm logon provider.
/// </summary>
logon32_provider_winnt40 = 2,

/// <summary>
/// windows xp/2000: use the negotiate logon provider.
/// </summary>
logon32_provider_winnt50 = 3
};

class secuutil32
{
[dllimport("advapi32.dll", setlasterror=true)]
public static extern bool logonuser(string lpszusername, string lpszdomain, string lpszpassword,
int dwlogontype, int dwlogonprovider, ref intptr tokenhandle);

[dllimport("kernel32.dll", charset=charset.auto)]
public extern static bool closehandle(intptr handle);

[dllimport("advapi32.dll", charset=charset.auto, setlasterror=true)]
public extern static bool duplicatetoken(intptr existingtokenhandle,
int security_impersonation_level, ref intptr duplicatetokenhandle);
}

public class networksecurity
{
public networksecurity()
{
//
// todo: add constructor logic here
//
}

/// <summary>
/// the impersonateuser function attempts to log a user on to the local computer.
/// the local computer is the computer from which impersonateuser was called.
/// you cannot use impersonateuser to log on to a remote computer.
/// you specify the user with a user name and domain, and authenticate the user with a clear-text password.
/// if the function succeeds, you receive a handle to a token that represents the logged-on user.
/// you can then use this token handle to impersonate the specified user, or in most cases,
/// to create a process running in the context of the specified user.
/// </summary>
/// <param name="strdomain">
/// specifies the name of the domain or server whose account database contains the strlogin account.
/// </param>
/// <param name="strlogin">specifies the name of the user.</param>
/// <param name="strpwd">specifies the clear-text password for the user account specified by strlogin.</param>
/// <param name="logontype">specifies the type of logon operation to perform.</param>
/// <param name="logonprovider">specifies the logon provider.</param>
/// <example>
/// //add system.security.dll
/// //using system.security.principal;
///
/// string strdomain=configurationsettings.appsettings["msalogindomainname"];
/// string struser=configurationsettings.appsettings["msalogindomainuser"];
/// string strpassword=configurationsettings.appsettings["msalogindomainpassword"];
///
/// windowsimpersonationcontext impcontext = null;
/// try
/// {
/// impcontext = networksecurity.impersonateuser(strdomain,struser,strpassword,
/// logontype.logon32_logon_service,
/// logonprovider.logon32_provider_default);
/// }
/// catch
/// {
///
/// }
///
/// //work under this logined user
///
/// impcontext.undo();
/// </example>
/// <returns>
/// </returns>
public static windowsimpersonationcontext impersonateuser(string strdomain,
string strlogin,
string strpwd,
logontype logontype,
logonprovider logonprovider)
{
// initialize tokens
intptr tokenhandle = new intptr(0);
intptr dupetokenhandle = new intptr(0);
tokenhandle = intptr.zero;
dupetokenhandle = intptr.zero;

// if domain name was blank, assume local machine
if (strdomain == "")
strdomain = system.environment.machinename;

try
{
const int securityimpersonation = 2;

// call logonuser to obtain a handle to an access token.
bool returnvalue = secuutil32.logonuser(
strlogin,
strdomain,
strpwd,
(int)logontype,
(int)logonprovider,
ref tokenhandle);

// did impersonation fail?
if (false == returnvalue)
{
int ret = marshal.getlastwin32error();
// throw the exception show the reason why logonuser failed
string strerr = string.format("logonuser failed with error code : {0}", ret);
throw new applicationexception(strerr, null);
}

// get identity before impersonation
bool retval = secuutil32.duplicatetoken(tokenhandle, securityimpersonation, ref dupetokenhandle);

// did duplicatetoken fail?
if (false == retval)
{
// close existing handle
secuutil32.closehandle(tokenhandle);
// throw the exception show the reason why duplicatetoken failed
throw new applicationexception("failed to duplicate token", null);
}

// create new identity using new primary token
// the token that is passed to the following constructor must
// be a primary token in order to use it for impersonation.
windowsidentity newid = new windowsidentity(dupetokenhandle);
windowsimpersonationcontext impersonateduser = newid.impersonate();

return impersonateduser;
}
catch (exception ex)
{
throw new applicationexception(ex.message, ex);
}
finally
{
// close handle
if (tokenhandle != intptr.zero)
secuutil32.closehandle(tokenhandle);
if (dupetokenhandle != intptr.zero)
secuutil32.closehandle(dupetokenhandle);
}
}
}
}


  • 本文来源于网页设计爱好者web开发社区http://www.html.org.cn收集整理,欢迎访问。
  • 发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表