将联系人添加到通讯组列表:Principal对象必须具有有效的SID IdentityType才能执行此操作

本文关键字:SID 有效 IdentityType 操作 执行 添加 联系人 对象 Principal 列表 | 更新日期: 2023-09-27 17:50:45

我正试图将Contact添加到分发列表中。

我是这样做的:

public void AddContactsToGroup(string groupName, string[] userNames)
{
         using (PrincipalContext context = GetPrincipalContext())
         {
            var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, groupName);
            if (group.IsSecurityGroup.HasValue && group.IsSecurityGroup.Value == true)
               throw new ArgumentException("Groups cannot be security groups.");
            foreach (var userName in userNames)
            {
               var query = new ContactPrincipal(context)
                              {
                                 Name = userName
                              };
               var user = Search(query).First();
               group.Members.Add(user);
            }
            group.Save(context);
         }
      }
  private List<T> Search<T>(T query) where T : Principal
  {
     var searcher = new PrincipalSearcher();
     searcher.QueryFilter = query;
     PrincipalSearchResult<Principal> results = searcher.FindAll();
     return results.Cast<T>().ToList();
  }

这是ContactPrincipal类(我从某处借来的):

   [DirectoryObjectClass("contact")]
   [DirectoryRdnPrefix("CN")]
   public class ContactPrincipal : AuthenticablePrincipal
   {
      public ContactPrincipal(PrincipalContext context)
         : base(context)
      {
      }
      public static ContactPrincipal FindByIdentity(PrincipalContext context, string identityValue)
      {
         return (ContactPrincipal) Principal.FindByIdentityWithType(context, typeof (ContactPrincipal), identityValue);
      }
      public static ContactPrincipal FindByIdentity(PrincipalContext context, IdentityType identityType,
                                                    string identityValue)
      {
         return
            (ContactPrincipal)
            Principal.FindByIdentityWithType(context, typeof (ContactPrincipal), identityType, identityValue);
      }
      [DirectoryProperty("mail")]
      public string EmailAddress
      {
         get
         {
            if (ExtensionGet("mail").Length == 1)
            {
               return ExtensionGet("mail")[0].ToString();
            }
            else
            {
               return null;
            }
         }
         set { ExtensionSet("mail", value); }
      }
      [DirectoryProperty("givenName")]
      public string GivenName
      {
         get
         {
            if (ExtensionGet("givenName").Length == 1)
            {
               return ExtensionGet("givenName")[0].ToString();
            }
            else
            {
               return null;
            }
         }
         set { ExtensionSet("givenName", value); }
      }
      [DirectoryProperty("middleName")]
      public string MiddleName
      {
         get
         {
            if (ExtensionGet("middleName").Length == 1)
            {
               return ExtensionGet("middleName")[0].ToString();
            }
            else
            {
               return null;
            }
         }
         set { ExtensionSet("middleName", value); }
      }
      [DirectoryProperty("sn")]
      public string Surname
      {
         get
         {
            if (ExtensionGet("sn").Length == 1)
            {
               return ExtensionGet("sn")[0].ToString();
            }
            else
            {
               return null;
            }
         }
         set { ExtensionSet("sn", value); }
      }
      [DirectoryProperty("mobile")]
      public string MobileTelephoneNumber
      {
         get
         {
            if (ExtensionGet("mobile").Length == 1)
            {
               return ExtensionGet("mobile")[0].ToString();
            }
            else
            {
               return null;
            }
         }
         set { ExtensionSet("mobile", value); }
      }
      [DirectoryProperty("telephoneNumber")]
      public string VoiceTelephoneNumber
      {
         get
         {
            if (ExtensionGet("telephoneNumber").Length == 1)
            {
               return ExtensionGet("telephoneNumber")[0].ToString();
            }
            else
            {
               return null;
            }
         }
         set { ExtensionSet("telephoneNumber", value); }
      }
   }
我的问题是,当我点击
group.Members.Add(user) 
AddContactsToGroup方法的

行中,抛出一个错误,表示

主体对象必须具有有效的SID IdentityType才能执行此操作。

当我询问ContactPrincipal的属性时,Sid实际上是空的。这并不奇怪,因为Contact是一个没有安全性的对象。

如何将Contact添加到非安全组?

将联系人添加到通讯组列表:Principal对象必须具有有效的SID IdentityType才能执行此操作

为什么不直接使用sid呢?否则,您使用什么来惟一地标识您的用户和组呢?GUID吗?


  1. 您确定ContactPrinciple搜索查询返回正确的结果吗?在。net Framework 3.5中发现如何管理目录安全主体一节可能会有所帮助。为什么不使用ContactPrincipal FindByIdentity而不是使用搜索查询来搜索每个用户呢?

  2. 沿着同样的行,也许你应该添加一行,将检查用户原则是否等于null之前,试图将其添加到组

    if(user != null){group.Members.Add(用户);}

  3. 此外,这个线程走向底部似乎描述了你所遇到的同样的问题。下面是用VB提供的解决方案。

    如何添加联系人到群组:)?由于某种原因添加联系人通过用于添加用户或控件的常规方法添加到组组到一个组会导致错误。为了解决这个问题,我使用了代码:

    Public Sub AddPrincipalToGroup(ByVal Group As GroupPrincipal, ByVal ChildPrincipal As Principal)
        ' use the underlying DirectoryEntry objects to avoid 
        ' issues surrounding contacts and other custom types
        Dim deGroup As DirectoryEntry = Group.GetUnderlyingObject()
        deGroup.Properties("member").Add(ChildPrincipal.DistinguishedName)
        deGroup.CommitChanges()
    End Sub
    

其他可能有用的链接:

  • 在。net中从Active Directory组中添加和删除用户
  • 如何通过ldap
  • 中的域名获取用户的用户名和SID
  • 我使用哪个Active Directory字段来唯一标识用户?

您的组或联系人的值可能不是预期的distinguishedName?

但是,没有理由认为联系人不能是安全组的成员,或者启用了安全的用户或组对象不能是通讯组的成员。

也许先回到最基本的?

假设用户有权限,这个(极简的)代码可以完美地工作。如果没有,使用正确的用户名和密码与directoryEntries。

public static void AddContactToGroup(string ContactDN, string GroupDN)
{
  try
  {
    using (DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://" + GroupDN))
    {
      directoryEntry.RefreshCache();
      DirectoryEntry Contactgroup = new DirectoryEntry("LDAP://" + ContactDN);
      directoryEntry.Properties["member"].Add(Contactgroup.Properties["distinguishedName"].Value);
      directoryEntry.CommitChanges();
    }
  }
  catch (Exception e)
  {
    string msg = e.Message.ToString();
    throw e;
  }
}

ContactDN是联系人的区分名。GroupDN为组的可区分名。

如果这对你有效,添加你需要的。如果不是。找出原因

听起来您的用户要么没有SID,要么正在尝试使用一个已经使用的SID。你看过SID是什么了吗?JSuar也是对的,对于AD,检查null总是一个好主意,AD对象可以返回null而不会抛出任何错误,null检查不会伤害任何人。