这是一个简单的问题,我已经坚持了一段时间。
当我在web.config中设置< identity impersonate=true >
以便asp.net自动模拟登录用户(或者如果不使用Windows身份验证则匿名帐户),asp.net模仿的身份来自何处?
本文档:http://msdn.microsoft.com/en-us/library/ff649264.aspx显示了三个可以检索登录用户信息的地方:
Httpcontext.Current.user
System.Threading.Thread.Current
System.Security.Principal.WindowsIdentity.GetCurrent
当我在web.config中设置< identity impersonate=true >
时,似乎这些位置都没有一致地与模拟的身份相匹配。
我想知道模仿身份的来源。
具体来说,我的意思是在较低的层次上询问,在运行时从哪里获取身份。我熟悉IIS的配置,但我想知道如何在运行时检索身份以及它来自何处。为了便于讨论,我们假设身份是在IIS中设置的,而不是在web.config文件中设置的。
答案 0 :(得分:8)
启用模拟后,身份来自IIS。会发生什么是ASP.NET模拟IIS提供的访问令牌。
用于运行流程的原始访问令牌仍然可用。这可能是围绕使用问题中提到的三个API的混淆的原因。
Thread.CurrentPrincipal
&amp; HttpContext.Current.User
:该行另一端的用户身份。
WindowsIdentity.GetCurrent
:正在执行的实际基础Windows帐户。
HttpContext.Current.User中重复的原因是ASP.NET开发人员的便利。
修改
当IIS配置为在集成Windows身份验证下运行时,和 ASP.NET启用了模拟,以下代码将使我们能够将代码作为基础帐户运行。
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
protected void Page_Load(object sender, EventArgs e)
{
var me = WindowsIdentity.GetCurrent();
// At this point:
// me.Name = Domain\UserName
// me.AuthenticationType = Kerberos
if (RevertToSelf())
{
var underMe = WindowsIdentity.GetCurrent();
// At this point:
// underMe.Name = IIS APPPOOL\DefaultAppPool
// underMe.AuthenticationType = Negotiate
}
}
根据您要执行的操作,此页面有更多方法可以解决问题:http://support.microsoft.com/kb/306158
答案 1 :(得分:4)
您无法将模拟部分与身份验证部分分开。我想你知道,因为你写了
... asp.net自动模拟登录用户(如果不使用Windows身份验证,则为匿名帐户)...
但我对句子感到困惑
为了便于讨论,我们假设身份是在IIS中设置的,而不是在web.config文件中设置的。
你到底是什么意思?
但是,无论如何,让我试着回答:
假设您在Web.config中使用IntegratedWindowsSecurity,<identity impersonate=true>
和<authentication mode=Forms>
。这将对应于您引用的Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication中最后一个表的倒数第二行。
它声明在这种情况下Domain\UserName
将从WindowsIdentity
返回。我假设你想知道Domain\UserName
- 身份来自哪里......使用Kerberos有一些限制,比如IE必须将URL分类为“Intranet”或“Local”但我认为这在这里并不重要
现在区分在Web.config中设置<authentication mode=windows>
和在IIS中将访问模式设置为IntegratedWindowsSecurity
(或其中所谓的任何内容)非常重要。在上述链接的最后一个表中,我们处于将IIS设置为IntegratedWindowsSecurity的情况(尽管我们可以在Web.config中设置<authentication mode="windows">
!)。因此,IE与IIS就如何验证当前登录的用户进行协商。使用NTLM或Kerberos(主要取决于Windows版本)。这就是Domain\UserName
的来源。
以下文章(谈论代表团,我知道)可能会更清楚地解决这个问题ASP.NET Delegation:
集成Windows身份验证
Internet Explorer尝试时 访问受保护的资源,IIS发送 两个WWW-Authenticate标头 浏览器,谈判和NTLM。该 协商标题仅由IIS发送 在Windows 2000或更高版本上运行。这个 header表示IIS支持 协商协议,它启用了一个 互联网之间的谈判 资源管理器和IIS是否使用 Kerberos或NTLM身份验证。 IIS 如果客户端都使用Kerberos (Internet Explorer 5.0及更高版本)和 服务器(IIS 5.0和更高版本)正在运行 Windows 2000或更高版本,两者都是 同一域的成员或受信任的成员 域。否则,服务器 默认使用NTLM。
由于NTLM对用户进行身份验证 IIS没有提供用户的 IIS的凭据,IIS不能 将该用户的凭据委托给 远程机器。
与Kerberos一起使用时 v5身份验证,IIS可以委派 计算机之间的安全凭证 运行Windows 2000或更高版本 信任并配置为委派。
您可能知道这些链接,但无论如何我都会发布这些链接:
修改强>
为了更准确一点,我想(不确定在这里)IIS从WindowsIdentity
创建LogonToken
(通过调用非托管Win32 LogonUser
得到的IntPtrStringTypeConstructor
函数)使用构造函数解释here in msdn。此外,WindowsIdentity Class文档中的示例代码非常有趣(例如Application_AuthenticateRequest
)。登录令牌必须来自IE。
Scott Hanselman也写了一篇类似的文章:System.Threading.Thread.CurrentPrincipal vs. System.Web.HttpContext.Current.User or why FormsAuthentication can be subtle。
如果您寻找将自定义主体对象“植入”到ASP.NET身份验证过程中的解决方案(通常在Global.asax
中使用{{1}}),我认为您可以提取其他信息。例如Using Custom Principal with Forms Authentication in ASP.NET。
或者您可以使用Reflector并自己查看:)
答案 2 :(得分:0)
如果您担心哪个实体对您的应用程序有影响,首先要注意的是您的身份验证模式,如(Windows,Form,Passport或None)
从验证您的请求的凭据读取的位置取决于您为应用程序选择的身份验证模式。
答案 3 :(得分:-1)
如果我没弄错,这是IIS中设置的标识。目录安全性。
答案 4 :(得分:-1)
过去我将身份设置为冒充 web.config文件。 在这种情况下,我创建了一个用户,将应用程序池设置为该用户,并使用该用户名进行模拟。