(这是一个关于模糊问题的问题.我尽量提供所有相关数据,希望有人提供有用的信息;对冗长的描述表示歉意.)
(This is a question about a vague problem. I try to present all relevant data, in the hope that someone has helpful information; apologies for the long description.)
我们的网络应用
我们有一个在 IIS 7.5 中运行的 .NET 4 Web 应用程序,用于访问 Active Directory 和 SQL Server 数据库.
We have a .NET 4 web application running in IIS 7.5 accessing Active Directory and a SQL Server database.
此 Web 应用程序在虚拟应用程序池标识"下运行,方法是将应用程序的应用程序池标识设置为 ApplicationPoolIdentity.虚拟身份的简明描述可以在一个 StackOverflow 答案中找到,以及它所引用的博客文章:应用程序池身份是只是一个额外的组,它被添加到作为网络服务"运行的 web 应用程序的工作进程中.但是,一个来源含糊地暗示网络服务和 ApplicationPoolIdentity 确实有IIS.net 站点文档未发布的差异."因此,虚拟身份可能不仅仅是一个附加组.
This web application is running under a virtual 'app pool identity', by setting the Identity of the application's application pool to ApplicationPoolIdentity. A concise description of virtual identities can be found in a StackOverflow answer, and the blog post to which it refers: an app pool identity is just an additional group which is added to the web application's worker processes which is running as 'network service'. However, one source vaguely suggests that "Network Service and ApplicationPoolIdentity do have differences that IIS.net site documents do not publish." So a virtual identity might be more than just an additional group.
我们选择使用 ApplicationPoolIdentity,而不是 NetworkService,因为它成为 IIS 7.5 中的默认设置(参见,例如,此处),并且根据 Microsoft 的建议:此标识允许管理员指定仅与运行应用程序池的标识有关的权限,从而提高服务器安全性."(来自 processModel Element for add for applicationPools [IIS 7 Settings Schema]) 应用程序池标识是一种强大的新隔离功能",它使运行 IIS 应用程序更加安全可靠."(来自 IIS.net 文章应用程序池标识")
We chose to use ApplicationPoolIdentity, as opposed to NetworkService, because it became the default in IIS 7.5 (see, e.g., here), and per Microsoft's recommendation: "This identity allows administrators to specify permissions that pertain only to the identity under which the application pool is running, thereby increasing server security." (from processModel Element for add for applicationPools [IIS 7 Settings Schema]) "Application Pool Identities are a powerful new isolation feature" which "make running IIS applications even more secure and reliable. " (from IIS.net article "Application Pool Identities")
应用程序使用集成的 Windows 身份验证,但使用 <identityimpersonate="false"/>
,这样就不会使用最终用户的身份,而是使用虚拟应用程序池身份来运行我们的代码.
The application uses Integrated Windows Authentication, but with <identity impersonate="false"/>
, so that not the end user's identity but the virtual app pool identity is used to run our code.
此应用程序使用 System.DirectoryServices 类,即 ADSI API.在大多数情况下,无需指定额外的用户名/密码或其他凭据即可完成此操作.
This application queries Active Directory using the System.DirectoryServices classes, i.e., the ADSI API. In most places this is done without specifying an additional username/password or other credentials.
此应用程序还使用连接字符串中的 Integrated Security=true
连接到 SQL Server 数据库.如果数据库是本地的,那么我们看到IIS APPPOOLOurAppPoolName
是用来连接数据库的;如果数据库是远程的,则使用机器帐户 OURDOMAINourwebserver$
.
This application also connects to a SQL Server database using Integrated Security=true
in the connection string. If the database is local, then we see that IIS APPPOOLOurAppPoolName
is used to connect to the database; if the database is remote, then the machine account OURDOMAINourwebserver$
is used.
我们的问题
我们经常遇到问题,即工作安装开始以下列方式之一失败.
We regularly have issues where a working installation starts to fail in one of the following ways.
当数据库在远程系统上时,数据库连接开始失败:用户'NT AUTHORITYANONYMOUS LOGON'登录失败.原因:基于令牌的服务器访问验证失败,出现基础结构错误.检查以前的错误."上一个错误是错误:18456,严重性:14,状态:11".所以现在似乎不再使用 OURDOMAINourwebserver$
,而是尝试匿名访问.(我们有轶事证据表明这个问题在 UAC 关闭时发生,在打开 UAC 后它消失了.但请注意,更改 UAC 需要重新启动...)IIS.net线程使用ApplicationPoolIdentity连接SQL",具体在一个回复.
When the database is on a remote system, then the database connection starts to fail: "Login failed for user 'NT AUTHORITYANONYMOUS LOGON'. Reason: Token-based server access validation failed with an infrastructure error. Check for previous errors." The previous error is "Error: 18456, Severity: 14, State: 11." So it seems that now OURDOMAINourwebserver$
is not used anymore, but instead anonymous access is attempted. (We have anecdotal evidence that this problem occurred when UAC was switched off, and that it went away after switching on UAC. But note that changing UAC requires a reboot...) A similar problem is reported in IIS.net thread "use ApplicationPoolIdentity to connect to SQL", specifically in one reply.
通过 ADSI (System.DirectoryServices) 进行的 Active Directory 操作开始失败,错误为 0x8000500C(未知错误")、0x80072020(发生操作错误.")或 0x200B(指定的目录服务属性或值不存在").
Active Directory operations through ADSI (System.DirectoryServices) start to fail with error 0x8000500C ("Unknown Error"), 0x80072020 ("An operations error occurred."), or 0x200B ("The specified directory service attribute or value does not exist").
从 Internet Explorer 登录应用程序开始失败,出现 HTTP 401 错误.但是,如果在 IIS 中,我们将 NTLM 放在 Negotiate 之前,则它会再次工作.(请注意,Kerberos 需要访问 AD,但 NTLM 不需要.) 中报告了类似的问题IIS.net 线程Window Authentication Failing with AppPool Identity".
Signing in to the application from Internet Explorer starts to fail, with HTTP 401 errors. But if in IIS we then put NTLM before Negotiate then it works again. (Note that access to AD is needed for Kerberos but not for NTLM.) A similar problem is reported in IIS.net thread "Window Authentication Failing with AppPool Identity".
我们的假设和解决方法
至少在将应用程序池从 ApplicationPoolIdentity 切换到 NetworkService 时,AD 和登录问题似乎总是会消失.(我们发现一份报告证实了这一点.)
At least the AD and sign-in problems always seem to go away when switching the application pool from ApplicationPoolIdentity to NetworkService. (We found one report confirming this.)
页面 ASP 页面上的身份验证问题疑难解答" 有一些与主要和次要令牌相关的建议,我觉得令人鼓舞的是它链接了我们的前两个错误:它提到了 NT AUTHORITYANONYMOUS LOGON
访问,以及 AD 错误 0x8000500C 和指定的目录服务属性或值不存在".
Page "Troubleshooting Authentication Problems on ASP Pages" has some suggestions related to primary vs. secondary tokens, and what I find encouraging is that it links the first two of our errors: it mentions NT AUTHORITYANONYMOUS LOGON
access, and AD errors 0x8000500C and "The specified directory service attribute or value does not exist".
(同一页面还提到了 ADSI 模式缓存问题,但我们能找到的关于该主题的所有内容都是旧的.现在我们认为这无关紧要.)
(The same page also mentions ADSI schema cache problems, but everything we can find on that topic is old. For now we consider this to be unrelated.)
基于上述,我们当前的工作假设是,只有在虚拟应用程序池标识下运行时,我们的 Web 应用程序(IIS?工作进程?)才会突然丢失其主要令牌,这样 IIS 就只有一个二级令牌,这样对 Active Directory 和 SQL Server 的所有访问都是匿名完成的,导致上述所有错误.
Based on the above, our current working hypothesis is that, only when running under a virtual app pool identity, our web application (IIS? worker process?) suddenly loses its primary token, so that IIS only has a secondary token, so that all access to Active Directory and SQL Server is done anonymously, leading to all of the above errors.
现在我们打算从 ApplicationPoolIdentity 切换到 NetworkService.希望这能让上述所有问题消失.但我们不确定;如果可能的话,我们想切换回来.
For now we intend to switch from ApplicationPoolIdentity to NetworkService. Hopefully this makes all of the above problems go away. But we are not sure; and we would like to switch back if possible.
我们的问题
上述假设是否正确,如果正确,这是 IIS/Windows/.NET 中的错误吗?在什么情况下会发生这种主要的代币丢失?
Is the above hypothesis correct, and if so, is this a bug in IIS/Windows/.NET? Under which circumstances does this primary token loss occur?
通过 Microsoft 支持,我发现我们遇到了 Microsoft 知识库文章 KB2545850.这仅在使用 ApplicationPoolIdentity 时发生.它很容易发生,即在更改机器帐户密码后(默认情况下每 30 天自动发生一次),然后重新启动 IIS(例如,通过 iisreset
).请注意,根据 Microsoft 和我们的观察,重新启动后问题就会消失.
Through Microsoft Support I found out that we ran into the issue described in Microsoft Knowledge Base article KB2545850. This only occurs when ApplicationPoolIdentity is used. It occurs very easily, namely, after the machine account password is changed (which by default happens automatically every 30 days), and then IIS is restarted (e.g., through iisreset
). Note that the problem goes away after a reboot, according to Microsoft and our observations.
根据 Microsoft 的说法,无法检查您的 Windows/IIS 是否已进入此状态.
According to Microsoft it is not possible to check if your Windows/IIS has gotten into this state.
Microsoft 在这篇知识库文章中附加了一个修补程序.没有任何迹象表明该修补程序何时会进入正式交付状态,并且该修补程序已经有 10 个月的历史了.在我们的具体案例中,我们决定改用 NetworkService.
Microsoft has a hotfix attached to this KB article. There is no indication when that hotfix will be rolled into an official delivery, and the hotfix is already 10 months old. In our specific case, we decided to switch to NetworkService instead.
这篇关于使用应用程序池标识的 IIS 应用程序丢失主令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!