c# - Active Directory 中的过滤器更改通知 : Create, 删除、取消删除

标签 c# .net events active-directory

我目前正在使用 Change Notifications in Active Directory Domain Services在 .NET 中,如所述 in this blog 。这将返回选定对象(或该对象的子树)上发生的所有事件。我现在想要过滤创建和删除(可能还包括取消删除)事件的事件列表。

我想告诉 ChangeNotifier 类仅观察创建/删除/取消删除事件。另一个解决方案是接收所有事件并在我这边过滤它们。我知道,在删除对象的情况下,返回的属性列表将包含属性 isDeleted ,其值为 True。但是有没有办法查看该事件是否代表对象的创建?在我的测试中,对于用户对象,usnchanged 的值始终为 usncreated+1,并且对于 OU 来说两者相等,但是在高频 AD 中可以保证这一点吗?还可以比较更改和修改的时间戳。我如何判断对象是否已被取消删除?

仅供记录,这里是代码的主要部分from the blog :

public class ChangeNotifier : IDisposable
{
    static void Main(string[] args)
    {
        using (LdapConnection connect = CreateConnection("localhost"))
        {
            using (ChangeNotifier notifier = new ChangeNotifier(connect))
            {
                //register some objects for notifications (limit 5)
                notifier.Register("dc=dunnry,dc=net", SearchScope.OneLevel);
                notifier.Register("cn=testuser1,ou=users,dc=dunnry,dc=net", SearchScope.Base);

                notifier.ObjectChanged += new EventHandler<ObjectChangedEventArgs>(notifier_ObjectChanged);

                Console.WriteLine("Waiting for changes...");
                Console.WriteLine();
                Console.ReadLine();

            }
        }
    }

    static void notifier_ObjectChanged(object sender, ObjectChangedEventArgs e)
    {
        Console.WriteLine(e.Result.DistinguishedName);
        foreach (string attrib in e.Result.Attributes.AttributeNames)
        {
            foreach (var item in e.Result.Attributes[attrib].GetValues(typeof(string)))
            {
                Console.WriteLine("\t{0}: {1}", attrib, item);
            }
        }

        Console.WriteLine();
        Console.WriteLine("====================");
        Console.WriteLine();
    }

    LdapConnection _connection;
    HashSet<IAsyncResult> _results = new HashSet<IAsyncResult>();

    public ChangeNotifier(LdapConnection connection)
    {
        _connection = connection;
        _connection.AutoBind = true;
    }

    public void Register(string dn, SearchScope scope)
    {
        SearchRequest request = new SearchRequest(
            dn, //root the search here
            "(objectClass=*)", //very inclusive
            scope, //any scope works
            null //we are interested in all attributes
            );



        //register our search
        request.Controls.Add(new DirectoryNotificationControl());

        //we will send this async and register our callback
        //note how we would like to have partial results

        IAsyncResult result = _connection.BeginSendRequest(
            request,
            TimeSpan.FromDays(1), //set timeout to a day...
            PartialResultProcessing.ReturnPartialResultsAndNotifyCallback,
            Notify,
            request
            );

        //store the hash for disposal later
        _results.Add(result);
    }


    private void Notify(IAsyncResult result)
    {
        //since our search is long running, we don't want to use EndSendRequest
        PartialResultsCollection prc = _connection.GetPartialResults(result);
        foreach (SearchResultEntry entry in prc)
        {
            OnObjectChanged(new ObjectChangedEventArgs(entry));
        }
    }



    private void OnObjectChanged(ObjectChangedEventArgs args)
    {
        if (ObjectChanged != null)
        {
            ObjectChanged(this, args);
        }
    }

    public event EventHandler<ObjectChangedEventArgs> ObjectChanged;

    #region IDisposable Members
    public void Dispose()
    {
        foreach (var result in _results)
        {
            //end each async search
            _connection.Abort(result);
        }
    }
    #endregion
}

public class ObjectChangedEventArgs : EventArgs
{
    public ObjectChangedEventArgs(SearchResultEntry entry)
    {
        Result = entry;
    }

    public SearchResultEntry Result { get; set; }
}

最佳答案

大约五年前,我参与了一个项目的设计审查,该项目最初使用 AD 更改通知。有人问了与您非常相似的问题。我可以分享我的内存,并且认为从那时起事情没有太大变化。我们最终切换到 DirSync。

似乎不可能仅从 AD 更改通知中获取创建和删除信息。我们发现更改通知导致足够多的事件监视大型目录,导致通知处理可能出现瓶颈并落后。这个 API 并不是为了扩展而设计的,但我记得性能/延迟并不是我们切换的主要原因。

是的,新对象的 usn 关系通常成立,尽管我认为在多 DC 场景中您可以为新用户获得 usncreated == usnchanged,但我们没有进行广泛的测试,因为...

对我们来说重要的是,更改通知只能在您的计算机 100% 运行的不切实际的假设下为您提供可靠的对象创建检测!在生产系统中,总有一些情况需要重新启动并 catch 或重新同步,我们切换到 DirSync,因为它有一种强大的方法来处理这些情况。

在我们的例子中,如果错过了对象创建,它可能会在不确定的时间内阻止向新用户发送电子邮件。这显然不好,我们需要确定。对于 AD 更改通知,正确重新同步需要更多工作并且难以测试。但对于 DirSync 来说,它更自然,并且有一个快速路径恢复机制,通常可以避免重新同步。为了安全起见,我认为我们每天都会触发一次完全重新同步。

DirSync 不像更改通知那么实时,但通过每分钟发出一次 DirSync 查询可以获得大约 30 秒的平均延迟。

关于c# - Active Directory 中的过滤器更改通知 : Create, 删除、取消删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24735828/

相关文章:

c# - 忽略其中一个字段的列表中不同项目的数量

c# - 字符串格式化 C# 解码?

C# Linq to SQL 无效转换异常

javascript - 如何使用内联 HTML onclick 和 jQuery 获取被点击的元素?

Java事件: Is this a good way to go about it?

c# - 插入的ListView项目的索引

c# - 当 "break all"没有响应时,如何调试无响应的 .Net 服务?

c# - ASP.NET Core 2.0 Web 应用部署和托管

c# - 如何只发布需要的依赖?

android - 图片按钮有什么用?