ASP.Net (IIS 7.5) 无需用户凭据即可查询 Active Directory
我有多个为 Intranet 构建的 Web 应用程序。我想让用户不必担心登录,因此这些应用程序在访问网站时会拉取当前登录的用户。我使用这段代码来实现这一点:
Dim userName As String = User.Identity.Name
CurrentUser = userName.Substring(userName.IndexOf("\") + 1)
这就像一个魅力,这里没有问题。下一步是查询该登录用户的 Active Directory 以提取各种信息。我目前的编码方式,它在开发方面就像一个魅力(典型,因为我没有运行 IIS)。
当我将其发布到 IIS 服务器(运行 IIS 7.5 的 Windows Server 2008 R2)时,问题就出现了,我收到指向代码中查询 Active Directory 的特定行的错误消息。有趣的是,这些应用程序上周运行良好。在我的服务器管理员执行最新一批 Windows 更新后(请注意,我使用 .Net Framework 4.0 运行它们),它们崩溃了。
在我设置每个应用程序以启用 Windows 身份验证之前,其他身份验证类型已被禁用。对于提供商来说,协商是#1,NTLM 是#2。对于高级设置,扩展保护 = 关闭,并选中启用内核模式身份验证。
我的 web.config 有以下设置:
<customErrors mode="Off"/>
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
</authorization>
这些是我的设置,一切都运转良好。现在,为了让它发挥作用,我需要交换提供者,因此 NTLM 是#1,而 Negotiate 是 #2。因此,用户的凭据未正确传入,AD 查询失败。这是我用于查询的编码:
Dim adSearchRoot As New DirectoryEntry("LDAP://DC=[DOMAIN],DC=com")
Dim adSearch As New DirectorySearcher(adSearchRoot)
adSearch.Filter = "(&(ObjectClass=User)(sAMAccountName=" & CurrentUser & "))"
Dim searchResult As SearchResult = adSearch.FindOne()
自从更新以来,当加载前面带有 Negotiate 的站点时,它在底线上失败,因为我没有为 DirectoryEntry 设置用户名/密码。即使我设置了用户名/密码,它仍然不能像以前那样 100% 工作。
所以我的问题是,我需要做什么才能让用户访问该网站,我可以知道他们的用户名,并且可以查询活动目录而不需要在 DirectoryEntry 中使用用户名/密码?
是IIS里的设置吗? 或者我需要重新编码吗? web.config 设置也许? 我是否需要恢复服务器更新并找出导致中断的原因?
感谢您提前的建议。如果您有任何问题需要帮助回答,请告诉我。
更新
我尝试按照 Matt 的建议,将以下剪辑添加到我的 web.config 文件中:
<security>
<authorization>
<add accessType="Deny" users="?" />
</authorization>
</security>
这不起作用。我做了一些阅读,然后进一步更改了此部分:
<location path="Default Web Site/NameOfApp">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false"/>
<windowsAuthentication enabled="true">
<providers>
<add value="Negotiate" />
<add value="NTLM" />
</providers>
</windowsAuthentication>
</authentication>
<authorization>
<add accessType="Deny" users="?" />
</authorization>
</security>
</system.webServer>
</location>
在执行此操作时,我还删除了 web.config 部分中较高的字符串。这也不起作用(仅供参考,这是一个很好的参考 http://www. iis.net/ConfigReference/system.webServer/security/authentication)
然后我被这篇文章绊倒了:http://social.technet.microsoft.com/Forums/en/winserverDS/thread/7deba16b-295a-4887-98f9-9f291ed49871 这似乎是类似的情况。这篇文章最终引用了“Double Hops”,在研究了这个并尝试了一些事情之后,这也没有解决我的问题。
下一步
我将在不同的 Server 2008 R2 系统上尝试新的 IIS 7.5 实现,并从头开始,看看问题是否会重现。
任何新的建议都会有很大的帮助。
I have multiple web applications that I've built for our intranet. I wanted to allow users to not worry about logging in, so these apps pull the currently logged on user when they hit the site. I used this code for this to happen:
Dim userName As String = User.Identity.Name
CurrentUser = userName.Substring(userName.IndexOf("\") + 1)
This works like a charm, no issues here. The next step is to query Active Directory for that logged in user to pull various information. How I currently have it coded, it works like a charm on the devleopment side (typical because I'm not running IIS).
The problem becomes when I publish it to my IIS server (Windows Server 2008 R2 running IIS 7.5), I get error messages that point to the specific line in my code that queries Active Directory. The interesting part is these apps were working great last week. They broke after my server admin did the latest batch of Windows Updates (please note, I am running them using .Net Framework 4.0)
Before I had each app setup so that Windows Authentication was Enabled, the other Authentication types were disabled. For providers, Negotiate is #1, NTLM is #2. For Advanced Settings, Extended Protection = Off, and Enable Kernel-mode authentication is checked.
My web.config has the following set:
<customErrors mode="Off"/>
<authentication mode="Windows" />
<authorization>
<deny users="?"/>
</authorization>
These were the settings I had, and everything worked like a charm. Now to get it to somewhat work I need to swap the providers around so NTLM is #1 and Negotiate is #2. Because of this, the user's credentials are not properly passed in and the AD query fails. This is the coding I'm using for the query:
Dim adSearchRoot As New DirectoryEntry("LDAP://DC=[DOMAIN],DC=com")
Dim adSearch As New DirectorySearcher(adSearchRoot)
adSearch.Filter = "(&(ObjectClass=User)(sAMAccountName=" & CurrentUser & "))"
Dim searchResult As SearchResult = adSearch.FindOne()
Ever since the updates, when loading the site with Negotiate in front, it fails on that bottom line because I don't have a username/password set for the DirectoryEntry. Even when I set a username/password, it still does not 100% work like it used to.
So my question becomes, what do I need to do so that the user accesses the site, I can know their username, and can query active directory without requiring the use of a username/password in the DirectoryEntry??
Is it a setting in IIS?
Or do I need to recode?
web.config setting perhaps?
Do I need to revert server updates and figure out which one causes the break to occur?
Thanks for the advice in advance. If you have any questions to help answer the question, let me know.
UPDATE
I tried as Matt suggested by adding the following clip to my web.config file:
<security>
<authorization>
<add accessType="Deny" users="?" />
</authorization>
</security>
This did not work. I did some reading, and then altered this section further:
<location path="Default Web Site/NameOfApp">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false"/>
<windowsAuthentication enabled="true">
<providers>
<add value="Negotiate" />
<add value="NTLM" />
</providers>
</windowsAuthentication>
</authentication>
<authorization>
<add accessType="Deny" users="?" />
</authorization>
</security>
</system.webServer>
</location>
In doing this I also removed the string that was higher up in my web.config section. This did not work either (fyi, this was a great reference http://www.iis.net/ConfigReference/system.webServer/security/authentication)
I then tripped across this article: http://social.technet.microsoft.com/Forums/en/winserverDS/thread/7deba16b-295a-4887-98f9-9f291ed49871 which seemed to be a similar situation. This article eventually referenced "Double Hops", after looking into this and trying a few things, this didn't solve my issue either.
Next Step
I am going to try a new IIS 7.5 implementation on a different Server 2008 R2 system and essentially start from scratch, to see if the problem recreates or not.
ANY new suggestions would be of great help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我能够在 Windows 2008 Server 上毫无问题地执行代码。我创建了一个新的 .NET 4.0 应用程序池并将其分配给 Web 应用程序。我更改了 web.config 以拒绝匿名访问并使用 Windows 身份验证。代码执行无异常。
看看您的 web.config 剪辑,我想知道这是否是您所缺少的:
在 system.webServer 部分中拥有此授权部分非常重要。 IIS 7 使用 system.webServer 部分来存储属于 IIS 6 中元数据库一部分的一些设置。
I was able to make the code execute without any problems on a Windows 2008 Server. I created a new .NET 4.0 application pool and assigned it to the web application. I changed the web.config to deny anonymous access and use Windows authentication. The code executed without exception.
Looking at your web.config clip, I wonder if this might be what you're missing:
It's important that you have this authorization section within the system.webServer section. IIS 7 uses the system.webServer section to store some settings that were part of the metabase in IIS 6.
我也有同样的问题。我是这样解决的:
对 DirectoryEntry 构造函数使用重载 4 of 5,它不仅允许路径,还允许用户名和密码。因此,您的 AD 连接应如下所示:
现在,使用服务帐户而不是“域\用户名”,然后使用服务帐户的密码作为密码。
我认为只要服务帐户是“域用户”组的成员,那么您应该能够查询AD没有问题。
I had this same problem. Here's how I solved it:
Use overload 4 of 5 for the DirectoryEntry constructor which allows for not only a path, but a username, and a password as well. So, your AD connection should look like this:
Now, instead of "DOMAIN\Username", use a service account and then for the password, obviously, use the password for the service account.
I think as long as the service account is a member of the "Domain Users" group, then you should be able to query AD no problem.