【问题标题】:Error with UserPrincipal.GetAuthorizationGroups() methodUserPrincipal.GetAuthorizationGroups() 方法出错
【发布时间】:2010-08-04 12:53:08
【问题描述】:

我在 Web 应用程序中使用 UserPrincipal 类的 GetAuthorizationGroups 方法时遇到问题。

使用以下代码,我收到“在尝试检索授权组时,发生错误 (5)”

PrincipalContext context = new PrincipalContext(ContextType.Domain, null, "DC=MyCompany,DC=COM", "username", "password");
UserPrincipal p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "joe.blogs");
var groups = p.GetAuthorizationGroups();

我相信这段代码在一定程度上是有效的。

  • 查看上下文对象时,我可以看到对象中的服务器和用户名/密码已正确解析
  • 查看 p 对象时,我可以看到 AD 详细信息已填充,例如电话号码等。

这是错误的堆栈跟踪。

[PrincipalOperationException: While trying to retrieve the authorization groups, an error (5) occurred.]
   System.DirectoryServices.AccountManagement.AuthZSet..ctor(Byte[] userSid, NetCred credentials, ContextOptions contextOptions, String flatUserAuthority, StoreCtx userStoreCtx, Object userCtxBase) +317279
   System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOfAZ(Principal p) +441
   System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroupsHelper() +78
   System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups() +11

通过从 PrincipalContext 构造函数中删除用户名和密码详细信息并将应用程序池(在 iis7 中)更改为以同一用户 (username@mycompany.com) 身份运行 - 以下代码有效。

PrincipalContext context = new PrincipalContext(ContextType.Domain, null, "DC=MyCompany,DC=COM");
UserPrincipal p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "joe.blogs");
var groups = p.GetAuthorizationGroups();

我需要让第一个示例中的代码工作 - 我不想以域用户身份运行应用程序池只是为了让这个代码工作。

【问题讨论】:

    标签: c# active-directory directoryservices


    【解决方案1】:

    我也处理过同样的问题。请参阅有关类似问题的讨论。 https://stackoverflow.com/a/8347817/2012977

    解决方法如下:

    public List<GroupPrincipal> GetGroups(string userName)
        {
            var result = new List<GroupPrincipal>();
            PrincipalContext ctx = GetContext(); /*function to get domain context*/
            UserPrincipal user = UserPrincipal.FindByIdentity(ctx, userName);
            if (user != null)
            {
                PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
    
                var iterGroup = groups.GetEnumerator();
                using (iterGroup)
                {
                    while (iterGroup.MoveNext())
                    {
                        try
                        {
                            Principal p = iterGroup.Current;
                            result.Add((GroupPrincipal) p);
                        }
                        catch (PrincipalOperationException)
                        {
                            continue;
                        }
                    }
                }
            }
    
            return result;
        }
    

    【讨论】:

      【解决方案2】:

      错误 5 表示 ERROR_ACCESS_DENIED,这表明存在权限相关问题。也就是说,下面的代码刚刚对我有用,在 Windows 7 上运行,网站作为默认应用程序池运行:

      .aspx 页面“正文”的内容:

      <asp:GridView ID="GridView1" runat="server">
      </asp:GridView>
      

      代码隐藏:

      protected void Page_Load(object sender, EventArgs e)
      {
          var Context = new PrincipalContext(ContextType.Domain, "logon_domain", "username", "password");
          var principal = UserPrincipal.FindByIdentity(Context, "user_to_query");
          var groups = principal.GetAuthorizationGroups();
      
          GridView1.DataSource = groups;
          GridView1.DataBind();
      }
      

      在我的示例中,logon_domaindomain_name\username 的左撇子,而不是您使用的域规范样式。我的解决方案可能适合您,也可能不适合您。如果不是,它确实指向某个地方的权限问题。

      【讨论】:

      • 谢谢 Rob,我在 PrincipalContext 构造函数中尝试了许多组合,但运气不佳。我认为我的问题的根本原因是知道应用程序用户调用 GetAuthorizationGroups() 方法的权限要求。我的应用程序用户已读取 OU 中对象的所有信息权限。目前我通过阅读用户的 memberOf 属性来做这件事。这只是第一层,不是递归的。
      • FWIW,我有一个版本在我使用 var Context = new PrincipalContext(ContextType.Domain, "logon_domain"); 的地方工作,所以上下文纯粹是一个域,并且在 Win7/默认应用程序池中也可以正常工作。您在域上运行代码的机器是否已加入?
      • 是的,已加入域。如果我将 PrincipalContext(ContextType.Domain, "logon_domain") 构造函数与网络服务 (AppPool) 一起使用,则它不起作用。如果我将 AppPool 更改为以与方法 PrincipalContext(ContextType.Domain, null, "DC=MyCompany,DC=COM", "username", "password") 中使用的用户相同的用户身份运行,它确实有效!
      • 您可以将解决方案发布为答案吗?
      【解决方案3】:

      让您的管理员查看返回错误代码 5 的用户的 AD 帐户。我今天遇到了这个问题,结果证明是该用户帐户的设置。有一个复选框可以继承未选中的安全设置(所有其他用户都已选中)。这为我解决了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-18
        • 2012-01-23
        • 2023-03-07
        • 1970-01-01
        • 2017-05-12
        • 1970-01-01
        • 2020-05-30
        • 2015-03-08
        相关资源
        最近更新 更多