通过ASP.net程序创建域帐户故障

简介:

我曾经成功地使用windows程序成功的创建了一批带邮箱的域帐户,但是,当我把这段代码交给我的一个同事(她负责开发Web应用)迁移到asp.net中后,只能创建域帐户,不能创建邮箱。为什么呢?

我们咨询了微软的工程师,他告诉我们,这是由于asp.net的权限不够,我们应该在asp.net模拟用户,这样就可以成功创建。

我将微软的相关文章摘录下来:

模拟IIS验证的帐户或用户

若要在收到ASP.NET应用程序中每个页的每个请求时模拟MicrosoftInternet信息服务(IIS)身份验证用户,必须在此应用程序的Web.config文件中包含<identity>标记,并将impersonate属性设置为true。例如:


<identityimpersonate="true"/>

为ASP.NET应用程序的所有请求模拟特定用户

若要为ASP.NET应用程序的所有页面上的所有请求模拟特定用户,可以在该应用程序的Web.config文件的<identity>标记中指定userName和password属性。例如:


<identityimpersonate="true"userName="accountname"password="password"/>

注意:在线程上模拟特定用户的进程的标识必须具有“作为操作系统的一部分”权限。默认情况下,Aspnet_wp.exe进程在名为ASPNET的计算机帐户下运行。不过,此帐户没有模拟特定用户所需的权限。如果您尝试模拟特定用户,则会出现一条错误信息。

要解决此问题,请使用下列方法之一:

•为ASPNET帐户(权限最低的帐户)授予“作为操作系统的一部分”权限。

注意:虽然此方法可以解决问题,但Microsoft不建议使用此方法。

•在Machine.config文件的<processModel>配置部分中,将运行Aspnet_wp.exe进程所使用的帐户更改为System帐户。

在代码中模拟身份验证用户

若要仅在运行代码特定部分时模拟身份验证用户(User.Identity),您可以使用以下代码。此方法要求身份验证用户标识的类型为WindowsIdentity。

VisualBasic.NET


DimimpersonationContextAsSystem.Security.Principal.WindowsImpersonationContext
DimcurrentWindowsIdentityAsSystem.Security.Principal.WindowsIdentity
currentWindowsIdentity=CType(User.Identity,System.Security.Principal.WindowsIdentity)
impersonationContext=currentWindowsIdentity.Impersonate()
'Insertyourcodethatrunsunderthesecuritycontextoftheauthenticatinguserhere.
impersonationContext.Undo()


VisualC#.NET


System.Security.Principal.WindowsImpersonationContextimpersonationContext;
impersonationContext=
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Insertyourcodethatrunsunderthesecuritycontextoftheauthenticatinguserhere.
impersonationContext.Undo();

VisualJ#.NET


System.Security.Principal.WindowsImpersonationContextimpersonationContext;
impersonationContext=
((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();
//Insertyourcodethatrunsunderthesecuritycontextoftheauthenticatinguserhere.
impersonationContext.Undo();


在代码中模拟特定用户

若要仅在运行代码特定部分时模拟特定用户,请使用以下代码:

VisualBasic.NET


<%@PageLanguage="VB"%>
<%@ImportNamespace="System.Web"%>
<%@ImportNamespace="System.Web.Security"%>
<%@ImportNamespace="System.Security.Principal"%>
<%@ImportNamespace="System.Runtime.InteropServices"%>
<scriptrunat=server>
DimLOGON32_LOGON_INTERACTIVEAsInteger=2
DimLOGON32_PROVIDER_DEFAULTAsInteger=0
DimimpersonationContextAsWindowsImpersonationContext
DeclareFunctionLogonUserALib"advapi32.dll"(ByVallpszUsernameAsString,_
ByVallpszDomainAsString,_
ByVallpszPasswordAsString,_
ByValdwLogonTypeAsInteger,_
ByValdwLogonProviderAsInteger,_
ByRefphTokenAsIntPtr)AsInteger
DeclareAutoFunctionDuplicateTokenLib"advapi32.dll"(_
ByValExistingTokenHandleAsIntPtr,_
ByValImpersonationLevelAsInteger,_
ByRefDuplicateTokenHandleAsIntPtr)AsInteger
DeclareAutoFunctionRevertToSelfLib"advapi32.dll"()AsLong
DeclareAutoFunctionCloseHandleLib"kernel32.dll"(ByValhandleAsIntPtr)AsLong
PublicSubPage_Load(ByValsAsObject,ByValeAsEventArgs)
IfimpersonateValidUser("username","domain","password")Then
'Insertyourcodethatrunsunderthesecuritycontextofaspecificuserhere.
undoImpersonation()
Else
'Yourimpersonationfailed.Therefore,includeafail-safemechanismhere.
EndIf
EndSub
PrivateFunctionimpersonateValidUser(ByValuserNameAsString,_
ByValdomainAsString,ByValpasswordAsString)AsBoolean
DimtempWindowsIdentityAsWindowsIdentity
DimtokenAsIntPtr=IntPtr.Zero
DimtokenDuplicateAsIntPtr=IntPtr.Zero
impersonateValidUser=False
IfRevertToSelf()Then
IfLogonUserA(userName,domain,password,LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,token)<>0Then
IfDuplicateToken(token,2,tokenDuplicate)<>0Then
tempWindowsIdentity=NewWindowsIdentity(tokenDuplicate)
impersonationContext=tempWindowsIdentity.Impersonate()
IfNotimpersonationContextIsNothingThen
impersonateValidUser=True
EndIf
EndIf
EndIf
EndIf
IfNottokenDuplicate.Equals(IntPtr.Zero)Then
CloseHandle(tokenDuplicate)
EndIf
IfNottoken.Equals(IntPtr.Zero)Then
CloseHandle(token)
EndIf
EndFunction
PrivateSubundoImpersonation()
impersonationContext.Undo()
EndSub
</script>

VisualC#.NET


<%@PageLanguage="C#"%>
<%@ImportNamespace="System.Web"%>
<%@ImportNamespace="System.Web.Security"%>
<%@ImportNamespace="System.Security.Principal"%>
<%@ImportNamespace="System.Runtime.InteropServices"%>
<scriptrunat=server>
publicconstintLOGON32_LOGON_INTERACTIVE=2;
publicconstintLOGON32_PROVIDER_DEFAULT=0;
WindowsImpersonationContextimpersonationContext;
[DllImport("advapi32.dll")]
publicstaticexternintLogonUserA(StringlpszUserName,
StringlpszDomain,
StringlpszPassword,
intdwLogonType,
intdwLogonProvider,
refIntPtrphToken);
[DllImport("advapi32.dll",CharSet=CharSet.Auto,SetLastError=true)]
publicstaticexternintDuplicateToken(IntPtrhToken,
intimpersonationLevel,
refIntPtrhNewToken);
[DllImport("advapi32.dll",CharSet=CharSet.Auto,SetLastError=true)]
publicstaticexternboolRevertToSelf();
[DllImport("kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolCloseHandle(IntPtrhandle);
publicvoidPage_Load(Objects,EventArgse)
{
if(impersonateValidUser("username","domain","password"))
{
//Insertyourcodethatrunsunderthesecuritycontextofaspecificuserhere.
undoImpersonation();
}
else
{
//Yourimpersonationfailed.Therefore,includeafail-safemechanismhere.
}
}
privateboolimpersonateValidUser(StringuserName,Stringdomain,Stringpassword)
{
WindowsIdentitytempWindowsIdentity;
IntPtrtoken=IntPtr.Zero;
IntPtrtokenDuplicate=IntPtr.Zero;
if(RevertToSelf())
{
if(LogonUserA(userName,domain,password,LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,reftoken)!=0)
{
if(DuplicateToken(token,2,reftokenDuplicate)!=0)
{
tempWindowsIdentity=newWindowsIdentity(tokenDuplicate);
impersonationContext=tempWindowsIdentity.Impersonate();
if(impersonationContext!=null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
returntrue;
}
}
}
}
if(token!=IntPtr.Zero)
CloseHandle(token);
if(tokenDuplicate!=IntPtr.Zero)
CloseHandle(tokenDuplicate);
returnfalse;
}
privatevoidundoImpersonation()
{
impersonationContext.Undo();
}
</script>

VisualJ#.NET


<%@Pagelanguage="VJ#"%>
<%@ImportNamespace="System.Web"%>
<%@ImportNamespace="System.Web.Security"%>
<%@ImportNamespace="System.Security.Principal"%>
<%@ImportNamespace="System.Runtime.InteropServices"%>
<scriptrunat=server>
publicstaticintLOGON32_LOGON_INTERACTIVE=2;
publicstaticintLOGON32_PROVIDER_DEFAULT=0;
WindowsImpersonationContextimpersonationContext;
/**@attributeDllImport("advapi32.dll")*/
publicstaticnativeintLogonUserA(StringlpszUserName,
StringlpszDomain,
StringlpszPassword,
intdwLogonType,
intdwLogonProvider,
System.IntPtr[]phToken);
/**@attributeDllImport("advapi32.dll",
CharSet=CharSet.Auto,SetLastError=true)*/
publicstaticnativeintDuplicateToken(System.IntPtrhToken,
intimpersonationLevel,
System.IntPtr[]hNewToken);
/**@attributeDllImport("kernel32.dll",CharSet=CharSet.Auto)*/
publicstaticnativebooleanCloseHandle(System.IntPtr[]handle);
/**@attributeDllImport("advapi32.dll",
CharSet=CharSet.Auto,SetLastError=true)*/
publicstaticnativebooleanRevertToSelf();
publicvoidPage_Load(Objects,System.EventArgse)
{
if(impersonateValidUser("username","domain","password"))
{
//Insertyourcodethatrunsunderthesecuritycontextofaspecificuserhere.
undoImpersonation();
}
else
{
//Yourimpersonationfailed.Therefore,includeafail-safemechanismhere.
}
}
privatebooleanimpersonateValidUser(StringuserName,Stringdomain,Stringpassword)
{
WindowsIdentitytempWindowsIdentity;
System.IntPtr[]token=newSystem.IntPtr[1];
System.IntPtr[]tokenDuplicate=newSystem.IntPtr[1];
if(RevertToSelf())
{
if(LogonUserA(userName,domain,password,LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,token)!=0)
{
if(DuplicateToken(token[0],2,tokenDuplicate)!=0)
{
tempWindowsIdentity=newWindowsIdentity(tokenDuplicate[0]);
impersonationContext=tempWindowsIdentity.Impersonate();
if(impersonationContext!=null)
{
CloseHandle(tokenDuplicate);
CloseHandle(token);
returntrue;
}
}
}
}
if(!token[0].Equals(System.IntPtr.Zero))
CloseHandle(token);
if(!tokenDuplicate[0].Equals(System.IntPtr.Zero))
CloseHandle(tokenDuplicate);
returnfalse;
}
privatevoidundoImpersonation()
{
impersonationContext.Undo();
}
</script>

注意:在线程上模拟特定用户的进程的标识必须具有“作为操作系统的一部分”权限。默认情况下,Aspnet_wp.exe进程在名为ASPNET的计算机帐户下运行。不过,此帐户没有模拟特定用户所需的权限。如果您尝试模拟特定用户,则会出现一条错误信息。

要解决此问题,请使用下列方法之一:

•为ASPNET帐户授予“作为操作系统的一部分”权限。

•在Machine.config文件的<processModel>配置部分中,将运行Aspnet_wp.exe进程所使用的帐户更改为System帐户。

目录
相关文章
|
2月前
|
域名解析 缓存 Linux
如何让你的.NET WebAPI程序支持HTTP3?
如何让你的.NET WebAPI程序支持HTTP3?
63 2
如何让你的.NET WebAPI程序支持HTTP3?
|
9月前
|
安全 Shell 数据库
「学习记录」.NET程序的数据库密码解密
「学习记录」.NET程序的数据库密码解密
|
10月前
|
XML 存储 JSON
使用自定义XML配置文件在.NET桌面程序中保存设置
本文将详细介绍如何在.NET桌面程序中使用自定义的XML配置文件来保存和读取设置。除了XML之外,我们还将探讨其他常见的配置文件格式,如JSON、INI和YAML,以及它们的优缺点和相关的NuGet类库。最后,我们将重点介绍我们为何选择XML作为配置文件格式,并展示一个实用的示例。
107 0
|
2月前
|
XML 开发框架 .NET
LabVIEW中加载.NET 2.0,3.0和3.5程序集
LabVIEW中加载.NET 2.0,3.0和3.5程序集
36 4
|
6天前
|
存储 安全 C#
技术心得记录:强命名的延迟与关联在.net程序集保护中的作用及其逆向方法
技术心得记录:强命名的延迟与关联在.net程序集保护中的作用及其逆向方法
|
6天前
|
开发框架 前端开发 JavaScript
程序与技术分享:ASP.NET发展史(【译】)
程序与技术分享:ASP.NET发展史(【译】)
12 0
|
7天前
|
网络协议
技术好文:Smark.Net实现简单聊天程序
技术好文:Smark.Net实现简单聊天程序
|
28天前
|
自然语言处理 C# 图形学
​一款开源的.NET程序集反编译、编辑和调试神器
本文介绍了.NET反编译和调试工具dnSpyEx的使用方法。dnSpyEx是dnSpy的非官方Fork版本,支持.NET Framework、.NET Core和Unity程序集的调试和编辑,具有多种语言界面。主要功能包括:浅色、蓝色和深色主题,调试支持,代码编辑以及多语言支持。用户可以从GitHub下载并直接运行dnSpyEx,无需安装。通过创建测试项目,编译成dll文件,然后使用dnSpyEx进行调试和编辑程序集中的代码和IL指令。此外,文章还提供了项目源码地址和相关优秀项目的链接。
|
2月前
|
开发框架 .NET 开发工具
LabVIEW加载.NET程序集
LabVIEW加载.NET程序集
33 1
|
8月前
|
开发框架 .NET 测试技术
.NET Core 日志记录程序和常用日志记录框架
本文主要内容为.NET Core的日志记录程序和常使用的日志记录框架的简单使用 首先,打开VS2019新建一个ASP.NET Core Web Api项目,项目创建好后会有一个集成好的天气预报的类和控制器,接下来,我们的方法就在天气控制器里完成。
57 0