C# 传入的凭据中的目录项不用于提交更改

C# 传入的凭据中的目录项不用于提交更改,c#,.net,windows,active-directory,C#,.net,Windows,Active Directory,我正在创建一个web应用程序,它连接到Active Directory,并允许用户从应用程序在Active Directory中编辑自己的详细信息 用户可以查看其他用户的详细信息,因此应用程序使用windows身份验证仅允许编辑用户自己的详细信息。显然,我不能为每个用户提供管理员权限来允许这样做,因此在设置目录条目时,我会向其传递管理员服务帐户的凭据 达到提交更改后,我可以看到ADEntry凭据是正确的。但是,它似乎没有使用传入的凭据,而是使用windows身份验证凭据 当管理员用户运行应用程序

我正在创建一个web应用程序,它连接到Active Directory,并允许用户从应用程序在Active Directory中编辑自己的详细信息

用户可以查看其他用户的详细信息,因此应用程序使用windows身份验证仅允许编辑用户自己的详细信息。显然,我不能为每个用户提供管理员权限来允许这样做,因此在设置目录条目时,我会向其传递管理员服务帐户的凭据

达到提交更改后,我可以看到ADEntry凭据是正确的。但是,它似乎没有使用传入的凭据,而是使用windows身份验证凭据

当管理员用户运行应用程序时,他们可以更改详细信息,但当非管理员用户运行应用程序时,他们在到达CommitChanges()时会出现错误-访问被拒绝。这使我相信它使用的是windows身份验证凭据,而不是DirectoryEntry(凭据)中提供的凭据

有什么想法吗? 我需要使用模拟吗

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();
}

这些方法是创建、立即处理,然后返回一些对象实例:

DirectoryEntry ADEntry()
{
使用(DirectoryEntry ADEntry=new DirectoryEntry(myDomain、myAdminServiceUsername、myAdminServicePassword、AuthenticationTypes.Secure))
{
返回试验;
}
}
DirectorySearcher ADSearcher()
{
使用(DirectorySearcher ADSearcher=new DirectorySearcher(ADEntry()))
{
返回搜索器;
}
}
因此:

。。。
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==新的directorySearcher(directoryEntry);
directorySearcher.Dispose();
directorySearcher.Filter=“(&(objectClass=user)(sAMAccountname=“+userToFind+”)”);
var searchResult=directorySearcher.FindOne();
不幸的是,我没有可供测试的广告,这可能不是您问题的根本原因。但是,我建议修复代码,在对象实例被释放后不要使用它们。以下可能是更好的方法:

SearchResult SearchResult;
使用(var directoryEntry=new directoryEntry(myDomain、myAdminServiceUsername、myAdminServicePassword、AuthenticationTypes.Secure))
使用(var directorySearcher=newdirectorysearcher(directoryEntry))
{
directorySearcher.Filter=“(&(objectClass=user)(sAMAccountname=“+userToFind+”)”);
searchResult=directorySearcher.FindOne();
}
//这里可以使用searchResult,它不是“IDisposable”。

显示正在使用块在
中创建并返回的
数据。
using
块将在超出该范围时处理
ADEntry
。我认为代码示例有点混乱。你能不能把它清理一下,以便更好地显示操作顺序?抱歉,我当时只复制了代码片段,现在应该更有意义了。调用SetProperty时,错误发生在_ADEntry.CommitChanges()处,但仅当以非管理员身份登录windows身份验证时。。。对前两个“方法”
ADEntry
ADSearcher
仍然有点困惑。这些应该是方法还是应该表示类/构造函数?
GetADSearchResult
方法是
new
-将它们初始化。询问,因为这仍然无法消除我的顾虑,即您正在使用已由
using
块处理的实例。这就是我尝试在记事本中编写代码的原因,因为我目前无法访问我的工作站。它们是方法GetADSearchResult中的“新”是一个拼写错误,被编辑掉了。using块不应引起问题,因为当我在SetProperty中中断时,\u ADEntry具有在ADEntry()中设置的正确myDomain、myAdminServiceUsername和myAdminServicePassword。我还可以使用相同的方法从active directory中检索详细信息。换句话说,在ADEntry()中创建的目录条目和在ADSearcher()中创建的Searcher都可以访问,并显示正确的信息。从其他方法,翻译不是
var directoryEntry=new directoryEntry吗(myDomain、myAdminServiceUsername、myAdminServicePassword、AuthenticationTypes.Secure);var de=directoryEntry;directoryEntry.Dispose();
尽管如此,我仍然不确定是否值得使用
使用
var directorySearcher==new directorySearcher(de);ds=directorySearcher;directorySearcher.Dispose();ds.Filter=”(&(objectClass=user)(sAMAccountname=“+userToFind+”);var searchResult=directorySearcher.FindOne();
不确定它是否会改变错误,但值得一试,这是我在一整天的搜索中发现的唯一建议,因此值得一试shot@KieranJack不,这并没有什么不同。
directoryEntry
和您的
de
都是指向同一对象实例的引用。一个实例仍然是正在处理。将对象分配给另一个变量不会执行任何类型的对象复制!根据我的经验,处理
DirectoryEntry
DirectorySearcher
对象通常没有任何价值。例外情况是,如果您正在循环数千个帐户;垃圾收集器没有时间跟上,因此设置对象的姿势有助于降低内存消耗。此外,使用时请始终进行处置(请参阅“备注”部分)