【问题标题】:PrincipalContextSearcher not returning correct results on extended principal typePrincipalContextSearcher 未在扩展主体类型上返回正确结果
【发布时间】:2015-03-20 16:43:33
【问题描述】:

我遇到了一个问题,如果我尝试扩展 UserPrincipalPrincipalContextSearcher > 使用扩展类作为查询过滤器时,不会返回正确的结果。

例如,如果我创建以下 UserPrincipal 的最小扩展

[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("user")]
public class UserPrincipalExtended : UserPrincipal
{
    public UserPrincipalExtended(PrincipalContext context) : base(context) { }
    public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled) { }
}

如果我使用(非扩展)UserPrincipal 进行搜索,如下所示:

    using (var searchCritera = new UserPrincipal(context))
    {
        searchCritera.SamAccountName = searchTerm;
        using (var searcher = new PrincipalSearcher(searchCritera))
        {
            foreach (var principal in searcher.FindAll())
            {
                ... do stuff
            }
        }
     }

它将正确地只返回用户帐户。但是,如果我使用 UserPrincipalExtended 而不是 UserPrincipal,它会返回与计算机的匹配项以及其他各种我不想要的行为。我想要做的就是能够添加一些额外的属性以在 UserPrincipal 中检索,但在添加任何内容之前简单地扩展类似乎会改变过滤行为。

我缺少什么以及如何使用扩展的 UserPrincipal 获取 PrincipalSearcher ?

【问题讨论】:

    标签: c# active-directory


    【解决方案1】:

    稍微了解一下发生了什么,我查看了在 PrincipalSearcher的封面下使用的 DirectorySearcher > 看看有什么不同。

    ((System.DirectoryServices.DirectorySearcher)(principalSearcher.GetUnderlyingSearcher())).Filter
    

    当使用 UserPrincipal 作为查询过滤器时,过滤器如下所示:

        Filter: "(&(objectCategory=user)(objectClass=user)(sAMAccountName=*searchTermWithWildcards*))"  string
    

    当使用 UserPrincipalExtended 作为查询过滤器时,过滤器如下所示:

        Filter:  "(&(objectClass=user)(sAMAccountName=*searchTermWithWildcards*))"    string
    

    它缺少 objectCategory

    我采用了以下可悲的 hack 来使其正常工作,但我希望有一种更好的方法来指定 objectCategory

    [DirectoryRdnPrefix("CN")]
    #region *UGLY CODE WARNING* Don't look in here....
    // When building the underlying DirectorySearcher filter the DirectoryObjectClass value is inserted in as: (objectClass={value})
    // The following injection will result in : (objectClass=user)(objectCategory=user)
    [DirectoryObjectClass("user)(objectCategory=user")]
    #endregion
    
    public class UserPrincipalExtended : UserPrincipal
    {
        public UserPrincipalExtended(PrincipalContext context) : base(context) { }
        public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled)
            : base(context, samAccountName, password, enabled) { }
    }
    

    【讨论】:

    • 您的“属性插入”太棒了! :D
    【解决方案2】:

    可以替换AdvancedSearchFilter 属性(使用new 而不是override,因为原始属性是只读的)并使用您想要使用AdvancedFilterSet 的任何自定义过滤器添加您自己的CustomAdvancedFilter

    [DirectoryRdnPrefix("CN")]
    [DirectoryObjectClass("user")]
    public class UserPrincipalExtended : UserPrincipal
    {
        public UserPrincipalExtended(PrincipalContext context) : base(context) {
            AdvancedSearchFilter = new CustomAdvancedFilter(this);
        }
        public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled) : base(context, samAccountName, password, enabled)
        {
            AdvancedSearchFilter = new CustomAdvancedFilter(this);
        }
    
        public new AdvancedFilters AdvancedSearchFilter { get; set; }
    }
    
    public class CustomAdvancedFilter : AdvancedFilters
    {
        public CustomAdvancedFilter(Principal principal) : base(principal)
        {
            AdvancedFilterSet("objectCategory", "user", typeof(string), MatchType.Equals);
        }
    }
    

    【讨论】:

    • 您也可以根据需要在构造函数之外设置AdvancedSearchFilter
    猜你喜欢
    • 2011-01-15
    • 1970-01-01
    • 2020-01-11
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多