2016-07-05 26 views
1

我有2個結構域,A和B.域A具有基組A包含用戶從域B
我的代碼:GroupPrincipal.GetMembers和交叉域成員錯誤

using (var context = new PrincipalContext(ContextType.Domain, DomainName, User, Password)) 
{ 

    using (var groupPrincipal = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, 
                   groupName)) 
    { 
     if (groupPrincipal == null) return null; 
     using (var principalSearchResult = groupPrincipal.GetMembers(true)) 
     { 
      var changedUsersFromGroup = 
       principalSearchResult 
       .Where(member => member is UserPrincipal) 
       .Where(member => IsModifiedUser(member, usnChanged)) 
       .Cast<UserPrincipal>() 
       .Select(adsUser => new AdsUser(adsUser)).Cast<IAdsUser>() 
       .ToArray(); 

      return changedUsersFromGroup; 
     } 
    } 

} 

系統.DirectoryServices.AccountManagement.PrincipalOperationException: 嘗試解析跨商店引用時,在主體的SID所指示的域中找不到目標主體 。

但是,如果我從這裏

new PrincipalContext(ContextType.Domain, DomainName, User, Password) 

到域B添加用戶,它工作正常。
我該如何解決它?

+0

如果您有時間去反編譯GAC中的相關程序集,您可能會看到此錯誤消息的條件是什麼條件。我個人的猜測是有一個當時連接問題給DC,所以這個消息是誤導性的。除非第二次嘗試,否則解決起來很難。 –

回答

0

發現問題並向MS報告爲錯誤。目前不可能做到這一點。淨:(但它通過查詢原生C++ api工作

0

檢查在未投射到UserPrincipal時其行爲是否有所不同,例如,

var changedUsersFromGroup = principalSearchResult.ToArray(); 

根據other threads這可能是一些問題。同樣根據MSDN,使用GetMembers(true)返回的主集合不包含組對象,只返回葉節點,因此也許根本不需要該投射。接下來,檢查這種搜索將返回多少結果。如果您的AD有許多用戶/嵌套組,最好儘量不要使用GetMembers(true)以確保它適用於小型用戶組。

0

看起來您正在定義域A的PrincipalContext(因此您可以獲取組),但由於組中的用戶在域B中定義,因此上下文無法訪問它們(因爲它是域A上下文)。

您可能需要爲域B定義第二個'PricipalContext`並針對它運行查詢並使用可能位於域A組中的用戶的SID列表來過濾對象(您需要獲取SID列表,而不會導致底層代碼嘗試並解決它們)。

希望它有幫助!

0

不幸的是我目前無法測試它,但也許你可以試試這個

var contextB = new PrincipalContext(ContextType.Domain, DomainName_B, User_B, Password_B) 
[..] 
    var changedUsersFromGroup = 
        principalSearchResult 
        .Where(member => member is UserPrincipal) 
        .Where(member => IsModifiedUser(member, usnChanged)) 
        .Select(principal => Principal.FindByIdentity(contextB, principal.SamAccountName)) 
        .Cast<UserPrincipal>() 
        .Select(adsUser => new AdsUser(adsUser)).Cast<IAdsUser>() 
        .ToArray(); 

這可以工作,但只,如果所有的成員都是當然的域B。如果它們在不同的域中混合使用,則可能必須先對其進行過濾並遍歷您的域。
或者,您可以使用域帳戶運行您的應用程序?然後不要傳遞用戶/密碼並將所需的訪問權限授予此帳戶以避免錯誤。
說明:域上下文將切換爲您檢索到的主體(如果您註釋掉新的AdsUser/IAdsUser Cast部分,則可以在調試模式下查看此主題)。這是一個,似乎導致例外。儘管這正是我無法測試的部分,但我認爲AdsUser的創建會爲目標域創建一個新的ldap Bind。這與「原始」證書失敗。 AdsUser是ActiveDS還是第三方的一部分?
如果傳遞證書使用基本身份驗證,我沒有找到任何提示,但我認爲它應該。使用應用程序憑證使用協商和「處理這個」到新的AdsUser(..)應該修復問題。