我正在创建一个连接到Active Directory的Web应用程序,并允许用户从该应用程序在Active Directory中编辑自己的详细信息。
用户可以看到其他用户的详细信息,因此该应用程序使用Windows身份验证仅允许编辑用户自己的详细信息。显然,我无法为每个用户提供Admin特权,因此在设置目录项时,我会向其传递管理服务帐户的凭据。
完成提交更改后,我可以看到ADEntry凭据正确。但是,它似乎没有使用传入的凭据,而是使用Windows身份验证凭据。
当管理员用户运行应用程序时,他们可以更改详细信息,但是当非管理员用户运行应用程序时,他们会收到错误-访问被拒绝-到达CommitChanges()时。这使我相信它使用的是Windows身份验证凭据,而不是DirectoryEntry(credentials)中提供的凭据。
有什么想法吗? 我需要使用模拟吗?
DirectoryEntry ADEntry()
{
using (DirectoryEntry ADEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure))
{
return ADEntry;
}
}
DirectorySearcher ADSearcher()
{
using(DirectorySearcher ADSearcher = new DirectorySearcher(ADEntry()))
{
return ADSearcher;
}
}
SearchResult GetADSearchResult(string userToFind)
{
SearchResult searchResult = new SearchResult();
DirectorySearcher ADS = ADSearcher();
ADS.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
searchResult = ADS.FindOne();
return searchResult;
}
void SetProperty(string userToFind, string propertyToChange, string newPropertyValue)
{
SearchResult searchResult = GetADSearchResult(userToFind);
DirectoryEntry _ADEntry = searchResult.GetDirectoryEntry();
if (_ADEntry.Properties.Contains(propertyToChange))
{
_ADEntry.Properties[propertyToChange].Remove(_ADEntry.Properties[propertyToChange].Value);
}
_ADEntry.Properties[propertyToChange].Insert(0, newPropertyValue);
_ADEntry.CommitChanges();
}
答案 0 :(得分:1)
这些方法正在创建,立即处理,然后返回一些对象实例:
DirectoryEntry ADEntry()
{
using (DirectoryEntry ADEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure))
{
return ADEntry;
}
}
DirectorySearcher ADSearcher()
{
using(DirectorySearcher ADSearcher = new DirectorySearcher(ADEntry()))
{
return ADSearcher;
}
}
所以这个:
...
DirectorySearcher ADS = ADSearcher();
ADS.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
searchResult = ADS.FindOne();
...
...可以有效地翻译为:
var directoryEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure);
directoryEntry.Dispose();
var directorySearcher = = new DirectorySearcher(directoryEntry);
directorySearcher.Dispose();
directorySearcher.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
var searchResult = directorySearcher.FindOne();
不幸的是,我没有可用的广告来进行测试,这很可能不是问题的根本原因。但是,我建议修复代码,使其在处置对象实例后不使用它们。以下可能是更好的方法:
SearchResult searchResult;
using (var directoryEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure))
using (var directorySearcher = new DirectorySearcher(directoryEntry))
{
directorySearcher.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
searchResult = directorySearcher.FindOne();
}
// It's OK to use searchResult here, it's not `IDisposable`.