2016-09-16 27 views
2

ユーザープリンシパルによってActive Directoryからユーザーのグループを取得したいと考えています。この作業のために、私は、次の静的関数を書いた:ユーザーはこのコードを実行するとSystem.DirectoryServices.AccountManagement.NoMatchingPrincipalException:グループの列挙中にエラーが発生しました。グループが見つかりませんでした

internal static List<ADGroup> GetGroupsByIdentity(UserPrincipal pUserPrincipal) 
{ 
    var lResult = new List<ADGroup>(); 

    if (pUserPrincipal != null) 
    { 
     PrincipalSearchResult<Principal> lGroups = pUserPrincipal.GetAuthorizationGroups(); 

     // iterate over all groups 
     foreach (Principal p in lGroups) 
     { 
      // make sure to add only group principals 
      if (p is GroupPrincipal) 
      { 
       var lGroupName = ""; 
       var lGroupSid = ""; 

       try 
       { 
        lGroupName = p.Name; 
        lGroupSid = p.Sid.Value; 

        if (!string.IsNullOrEmpty(lGroupName) && !string.IsNullOrEmpty(lGroupSid) && 
         !lResult.Any(x => x.Sid == lGroupSid)) 
        { 
         lResult.Add(new ADGroup(p)); 
        } 
       } 
       catch (Exception e) 
       { 
        if (e is PrincipalOperationException || e is NoMatchingPrincipalException) 
        { 
         // perhaps the SID could not be resolved 
         // perhaps the SID does not exist in the AD any more 
         // ignore and proceed with next 

         p.Dispose(); 
         continue; 
        } 
        else 
        { 
         throw; 
        }       
       } 
       finally 
       { 
        p.Dispose(); 
       } 
      } 

      p.Dispose(); 
     } 
    } 

    return lResult; 
} 

は、彼が例外を取得します。ここにスタックの一部があります。

System.DirectoryServices.AccountManagement.NoMatchingPrincipalException: 
An error occurred while enumerating the groups. The group could not be found. 
at System.DirectoryServices.AccountManagement.AuthZSet.get_CurrentAsPrincipal() 
at System.DirectoryServices.AccountManagement.FindResultEnumerator`1.get_Current() 
at xxx.xxxxxxxxx.Mvc.CustomSetup.ADHandler.GetGroupsByIdentity(UserPrincipal pUserPrincipal) // the function above 
at ... 

問題はどこにありますか?どのように解決できますか?

答えて

4

GetAuthorizationGroups()メソッドにはいくつかの制限があるようです。これは2009年以来存在していた古い例外です。マイクロソフトでは、「合理的な回避策があるため」、修正することはありません。 https://connect.microsoft.com/VisualStudio/feedback/details/522539/clr-forum-error-calling-principal-getauthorizationgroups-in-winxp-sp3

Principal.IsMemberOf()を使用しているときにこのエラーが発生しました。ユーザーがグループのカスタムリストに存在するかどうかを調べました。グループがドメイン内に存在しなかった場合、それは.GetAuthorizationGroupsを用い.IsMemberOfを使用して、この

System.DirectryServices.AccountManagement.NoMatchingPrincipalException 

https://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.nomatchingprincipalexception(v=vs.110).aspx

エラー例1()

List<string> groups = Constants.ADGroups(); // List of AD groups to test against    

var context = new PrincipalContext(
    ContextType.Domain, 
    "Domain"); 

var userPrincipal = UserPrincipal.FindByIdentity(
    context, 
    IdentityType.SamAccountName, 
    httpContext.User.Identity.Name); 

// Verify that the user is in the given AD group (if any) 
foreach (var group in groups) 
    if (userPrincipal.IsMemberOf(context, IdentityType.Name, group)) 
     return true; 

エラー例2を投げ():

var context = new PrincipalContext(ContextType.Domain,"Domain"); 

var userPrincipal = UserPrincipal.FindByIdentity(
            context, 
            IdentityType.SamAccountName, 
            httpContext.User.Identity.Name); 

if (userPrincipal != null) 
{ 
    var principalGroups = userPrincipal.GetAuthorizationGroups(); 
    foreach (var principalGroup in principalGroups) 
    { 
     foreach (var group in groups) 
     { 
      if (String.Equals(
       principalGroup.Name, 
       group, 
       StringComparison.CurrentCultureIgnoreCase)) 
      { 
       return true; 
      } 
     } 
    } 
} 

解決方法1:

GetAuthorizationGroups() is throwing exception

PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups(); 
var iterGroup = groups.GetEnumerator(); 
using (iterGroup) 
{ 
    while (iterGroup.MoveNext()) 
    { 
     try 
     { 
      Principal p = iterGroup.Current; 
      Console.WriteLine(p.Name); 
     } 
     catch (NoMatchingPrincipalException pex) 
     { 
      continue; 
     } 
    } 
} 

解決方法2:

:私が代わりに(Windows認証を使用してMVCアプリ)を使用して終了何案問題を回避するには、ADグループを反復処理することです

これは、大企業の広告を反復するauthを確認するより軽い方法です...

var wi = HttpContext.Current.User.Identity as WindowsIdentity; 
if (wi != null) 
{ 
    var wp = new WindowsPrincipal(wi); 
    List<string> groups = Constants.ADGroups(); // List of AD groups to test against 

    foreach (var @group in groups) 
    { 
     Debug.WriteLine($"Searching for {@group}"); 
     if (wp.IsInRole(@group)) 
     { 
      return true; 
     } 
    } 
} 
+0

私は列挙子を使用し、正常に動作します。ありがとうございました。 – Simon

関連する問題