是否可以通过在 ASP.NET 中模拟 Windows 身份验证用户来从 Active Directory 检索数据?

发布于 2024-11-24 09:18:55 字数 1234 浏览 2 评论 0原文

我一整天都在试图解决这个问题,并且我在标准谷歌留言板答案中读到了一些相互矛盾的信息。

我想做的是从活动目录中检索域用户(即当前登录用户)的电子邮件地址。我的 ASP.NET 4 网站设置为 Windows 身份验证,在 Active Directory 调用之前一切正常。

当我执行以下操作时,我在 search.findAll() 行上收到 COMException。异常消息是“发生操作错误”(非常有用的消息,嗯?) (为了可读性而精简代码)

WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext wic = null;

wic = winId.Impersonate();
using (DirectoryEntry root = new DirectoryEntry(rootQuery))
{
      String userQuery = GetUserQuery();
      DirectorySearcher searcher = new DirectorySearcher(root);
      searcher.SearchScope = SearchScope.Subtree;
      searcher.Filter = userQuery;

      SearchResultCollection results = searcher.FindAll();
      return (results[0].Properties["proxyaddresses"][0]).ToString();
}

所以基本上我想模拟登录用户来拨打电话。 请注意,如果我将凭据直接传递给 DirectoryEntry 构造函数,则此代码将按预期工作。此外,如果我删除模拟代码并在 Web 配置中设置应用程序范围模拟,我也会收到相同的错误。

所以我想我的问题是,在我浪费更多时间之前,这可能吗?或者您必须指定访问 AD 的用户名和密码吗?

顺便说一句,我在我的开发盒上运行的是 IIS5,但可能会部署到 IIS6。

编辑:

根据要求:

rootQuery = @"LDAP://{0}.com/DC={0}, DC=com";
userQuery = @"(&(samAccountName={0})(objectCategory=person)(objectClass=user))";

指定正确的域和用户。

I've been trying to solve this problem all day, and I've read some conflicting information within the standard google message board answers.

What I'm trying to do is retrieve a domain user's (that is, the currently logged in user's) email address from active directory. My ASP.NET 4 website is setup for Windows Authentication and everything works fine until the active directory calls.

When I do the following, I get a COMException on the search.findAll() line. The exception message is "An operations error occured" (Very helpful message eh?)
(Stripped down code for readability)

WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext wic = null;

wic = winId.Impersonate();
using (DirectoryEntry root = new DirectoryEntry(rootQuery))
{
      String userQuery = GetUserQuery();
      DirectorySearcher searcher = new DirectorySearcher(root);
      searcher.SearchScope = SearchScope.Subtree;
      searcher.Filter = userQuery;

      SearchResultCollection results = searcher.FindAll();
      return (results[0].Properties["proxyaddresses"][0]).ToString();
}

So basically I want to impersonate the logged in user to make the call.
Note this code works as expected if I pass in my credentials directly to the DirectoryEntry constructor. Also, I receive the same error if I get rid of the impersonation code and set application wide impersonation in the web config.

So I guess my question, before I waste any more time on this, is this even possible? Or do you have to specify a username and password to access AD?

BTW on my dev box I'm running IIS5, but will probably deploy to IIS6.

edit:

as requested:

rootQuery = @"LDAP://{0}.com/DC={0}, DC=com";
userQuery = @"(&(samAccountName={0})(objectCategory=person)(objectClass=user))";

with the proper domain and user specified.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

阳光①夏 2024-12-01 09:18:55

您正在尝试模拟用户来访问外部资源(外部意味着不在同一服务器上)。您可以执行此操作,但您需要在活动目录中设置委派,以便 IIS 服务器(或现在的 WindowsXP 机器)可信任委派。如果这是您想要的方向,请查看其中一些资源以开始使用。

或者,为了避免正确设置和配置委派的麻烦,我只需创建一个服务帐户在活动目录中并使用它。您可以在代码中使用凭据,就像您之前所说的那样,或者使用 web.config 中的 Impersonation 元素来模拟此服务帐户: .

You are trying to impersonate a user to access an external resource (external meaning not on the same server). You CAN do this, but you will need to setup delegation in active directory so that the IIS server (or your WindowsXP box for now) is trusted for delegation. Check out some of these resources to get started if this is the direction you want to go.

Alternatively, to avoid the hastle of setting up and configuring delegation properly I just create a service account in active directory and use it instead. You can either use the credentials in your code, like you said worked earlier, or use the Impersonation element in web.config to impersonate this service account: <identity impersonate="true" userName="DOMAIN\ServiceAccount" password="password"/>.

残龙傲雪 2024-12-01 09:18:55

正如 @Patricker 提到的,您必须启用委派才能支持这种情况。还要确保您使用支持委派的身份验证机制。如果使用 Kerberos 对 Web 服务器的用户进行身份验证,则可以进行委派,但不能使用 NTLM[1]。如果您使用基本身份验证委托也是可能的(因为 Web 服务器可以访问客户端的用户名和密码)。

As @Patricker mentions you have to enable delegation to support this scenario. Also make sure that you use an authentication mechanism that supports delegation. If you use Kerberos to authenticate the user to the web server, delegation is possible, but not with NTLM[1]. If you use basic authentication delegation is also possible (as the web server has access to username and password of the client).

断爱 2024-12-01 09:18:55

如果我没记错的话,如果应用程序池作为网络服务而不是域帐户运行,这里会遇到一些挑战。你的如何配置?

另外,您可以发布 rootQuery 的值和 userQuery 的结果值吗?

If I remember right, there were some challenges here if the app pool was running as Network Service vs a domain account. How is yours configured?

Also, can you post the value of rootQuery and the resultant value for userQuery?

酸甜透明夹心 2024-12-01 09:18:55

还注意到代码中搜索 LDAP 的方式看起来性能成本非常昂贵。您可能想要使用 sid 搜索来查询 LDAP,可以在附加中找到该搜索链接

Also noticed the way in the code to search LDAP looks very performance cost expensive. You might want to query LDAP using sid search, which can be found in attached link

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文