【发布时间】:2012-12-11 13:40:11
【问题描述】:
我遵循tutorial 在 ASP.NET/C# 4.0 Web 应用程序上实现 LDAP 身份验证。虽然事情似乎确实有效,但当我将网站置于 IIS7 下时,它无法获取组名。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Collections;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
namespace KEWeb
{
public class LdapAuthentication
{
private string _path;
private string _filterAttribute;
private string _username;
private string _password;
private string _domain;
private string _domainAndUsername;
private DirectoryEntry _entry;
private DirectorySearcher _search;
private SearchResult _result;
public LdapAuthentication(string path, string domain, string username, string password)
{
_path = path;
_domain = domain;
_username = username;
_password = password;
_domainAndUsername = _domain + @"\" + _username;
_entry = new DirectoryEntry(_path, _domainAndUsername, _password);
}
public bool IsAuthenticated()
{
try
{
Object obj = _entry.NativeObject;
_search = new DirectorySearcher(_entry);
_search.Filter = "(SAMAccountName=" + _username + ")";
_search.PropertiesToLoad.Add("cn");
_result = _search.FindOne();
if (null == _result) { return false; }
_path = _result.Path;
_filterAttribute = (String)_result.Properties["cn"][0];
}
catch (Exception ex) { throw new Exception("Error authenticating user: " + ex.Message); }
return true;
}
public string GetGroups()
{
string r = "";
try
{
Object obj = _entry.NativeObject;
_search = new DirectorySearcher(_entry);
_search.Filter = "(SAMAccountName=" + _username + ")";
_search.PropertiesToLoad.Add("cn");
_result = _search.FindOne();
if (null != _result)
{
_path = _result.Path;
_filterAttribute = (String)_result.Properties["cn"][0];
_search = new DirectorySearcher(_path);
_search.Filter = "(cn=" + _filterAttribute + ")";
_search.PropertiesToLoad.Add("memberOf");
StringBuilder groupNames = new StringBuilder();
_result = _search.FindOne();
int propertyCount = _result.Properties["memberOf"].Count;
String dn;
int equalsIndex, commaIndex;
for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
{
dn = (String)_result.Properties["memberOf"][propertyCounter];
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if (-1 == equalsIndex) { return null; }
groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
groupNames.Append("|");
}
r = groupNames.ToString();
}
}
catch (Exception ex) { throw new Exception("Error obtaining group names: " + ex.Message); }
return r;
}
}
}
在 Visual Studio 2010 的调试中运行它时,它工作正常。但是在 IIS7 上,它给出了一个错误An operations error occured. Not sure how to debug this while under IIS,虽然我确信这是可能的。如果我完全忽略 GetGroups() 并将该代码注释掉,它可以工作,但我当然需要这些组名。
PS - 是的,上面的代码与原始代码完全不同,我对其进行了调整以重新使用一些多余的东西。然而,在我改变它之前,我确实遇到了这个问题。
【问题讨论】:
-
这是目录权限问题吗?换句话说:连接到 IIS 服务器的用户(或机器)是否有权执行查询?在我的场景中,我的开发框不是目录的成员。我会查询,并在几乎所有查询中获得 DirectoryServicesCOMException。
-
如果是这种情况,那么情况就会相反,因为正在工作的是标准用户,而 IIS 机器是域管理员,但是 IIS 再次在会话 0 中运行. 两台机器都属于同一个子网中的同一个域。
-
在我们的环境中,我们必须将应用程序池的身份设置为有权访问目录的用户。
-
我很确定这是问题所在,只是在更改后,我仍然遇到同样的问题。