并非所有的任务都可以通过修改对象的属性来执行。有时,必须修改对象的安全描述符。例如,默认情况下,一般用户可以读取其大多数属性,但是无法对其进行修改。您可能希望用户既能够对其电话号码进行读取,也能够进行写入。通过将访问控制项 (ACE) 添加到用户对象的随机访问控制列表 (DACL),可以做到这一点。此 ACE 是允许 ACE,允许对 telephoneNumber 属性进行写入访问。有关 telephoneNumber 属性的详细信息,请参阅 MSDN Library(网址为 https://go.microsoft.com/fwlink/?LinkID=27252)中的 telephoneNumber 主题或 Telephone-Number 主题。
在 .NET Framework 的 1.0 和 1.1 版中,不存在对修改 Active Directory 对象的安全描述符的本机支持。通过调用 ADSI 并使用 IADsSecurityDescriptor 和关联接口,可以操作 Active Directory 对象的安全描述符。有关详细信息,请参阅调用 ADSI。有关 IADsSecurityDescriptor 接口的更多信息,请参阅 MSDN Library(网址为 https://go.microsoft.com/fwlink/?LinkID=27252)中的 IADsSecurityDescriptor 主题。
在 .NET Framework 2.0 中,System.DirectoryServices 命名空间包含几个类,通过这些类可以操作安全描述符而无须调用 ADSI。用于 Active Directory 对象安全描述符的主类是 ActiveDirectorySecurity。您可以获取 ActiveDirectorySecurity 对象,该对象通过 ObjectSecurity 属性表示 Active Directory 对象的安全描述符。
ActiveDirectorySecurity 类具有很多方法和属性,这些方法和属性允许读取和修改对象的随机访问控制列表和辅助访问控制列表。
随机访问控制列表中的访问控制项称为访问规则。表示访问规则的主类是 ActiveDirectoryAccessRule 类。还有一些从 ActiveDirectoryAccessRule 类派生的类,它们用于表示特定类型的访问规则。下表列出了这些特定类及其用法。
| 类 | 用法 | 
|---|---|
| 表示一种访问规则,该规则用于允许或拒绝某个 Active Directory 对象具有创建子对象的权限。 | |
| 表示一种访问规则,该规则用于允许或拒绝某个 Active Directory 对象具有删除子对象的权限。 | |
| 表示一种访问规则,该规则用于允许或拒绝某个 Active Directory 对象具有删除所有子对象的权限。 | |
| 表示一种访问规则,该规则用于允许或拒绝某个 Active Directory 对象具有扩展权限。 | |
| 表示一种访问规则,该规则用于允许或拒绝某个 Active Directory 对象具有列出子对象的权限。 | |
| 表示一种访问规则,该规则用于允许或拒绝对 Active Directory 属性的访问。 | |
| 表示一种访问规则,该规则用于允许或拒绝对 Active Directory 属性集的访问。 | 
系统访问控制列表中的访问控制项称为审核规则,它由 ActiveDirectoryAuditRule 类表示。
在很多情况下,将访问规则添加到各个单独的对象以允许或拒绝对某项的访问是不切实际的。在这些情况下,最好修改容器的安全描述符并将访问规则设置为可继承。这还能确保在创建新对象时,它们将自动获取相应的权限。在上面的 telephoneNumber 示例中,您可能希望允许所有用户对其电话号码进行写入访问。执行此操作最简单的方法是,将可继承的访问规则添加到容器(如组织单位)并将所有用户置于组织单位下。下面的代码示例说明具体做法。
示例
下面的 Visual Basic .NET 示例说明如何将访问规则添加到容器,以便将 telephoneNumber 属性的写入访问权限授予容器的所有子对象(且为用户对象)。有关 telephoneNumber 属性的详细信息,请参阅 MSDN Library(网址为 https://go.microsoft.com/fwlink/?LinkID=27252)中的 telephoneNumber 主题或 Telephone-Number 主题。
Sub SetWritePhonePermission(ByVal container As DirectoryEntry)
    Try
        ' Get the ActiveDirectorySecurity for the container.
        Dim containerSecurity As ActiveDirectorySecurity
        containerSecurity = container.ObjectSecurity
        ' Create a SecurityIdentifier object for "self".
        Dim selfSid As New SecurityIdentifier(WellKnownSidType.SelfSid, _
            Nothing)
        ' Get the schema for the currently logged on user.
        Dim schema As ActiveDirectorySchema
        schema = ActiveDirectorySchema.GetCurrentSchema()
        ' Get the telephoneNumber schema property object.
        Dim phoneProperty As ActiveDirectorySchemaProperty
        phoneProperty = schema.FindProperty("telephoneNumber")
        ' Get the user schema class object.
        Dim userClass As ActiveDirectorySchemaClass
        userClass = schema.FindClass("user")
        ' Create a property access rule to allow a user to write to their own telephoneNumber property.
        Dim allowWritePhoneRule As New PropertyAccessRule(selfSid, _
            AccessControlType.Allow, _
            PropertyAccess.Write, _
            phoneProperty.SchemaGuid, _
            ActiveDirectorySecurityInheritance.Descendents, _
            userClass.SchemaGuid)
        ' Add the access rule to the DACL.
        container.ObjectSecurity.AddAccessRule(allowWritePhoneRule)
        ' Commit the changes.
        container.CommitChanges()
    Catch notFoundEx As ActiveDirectoryObjectNotFoundException
        ' The schema class or property could not be found.
    End Try
End Sub 'SetWritePhonePermission
下面的 C# 示例说明如何将访问规则添加到容器,以便将 telephoneNumber 属性的写入访问权限授予容器的所有子对象(且为用户对象)。有关 telephoneNumber 属性的详细信息,请参阅 MSDN Library(网址为 https://go.microsoft.com/fwlink/?LinkID=27252)中的 telephoneNumber 主题或 Telephone-Number 主题。
static void SetWritePhonePermission(DirectoryEntry container)
{
    try
    {
        // Get the ActiveDirectorySecurity for the container.
        ActiveDirectorySecurity containerSecurity = container.ObjectSecurity;
        // Create a SecurityIdentifier object for "self".
        SecurityIdentifier selfSid =
            new SecurityIdentifier(WellKnownSidType.SelfSid, null);
        // Get the schema for the currently logged on user.
        ActiveDirectorySchema schema = ActiveDirectorySchema.GetCurrentSchema();
        // Get the telephoneNumber schema property object.
        ActiveDirectorySchemaProperty phoneProperty = schema.FindProperty("telephoneNumber");
        // Get the user schema class object.
        ActiveDirectorySchemaClass userClass = schema.FindClass("user");
        // Create a property access rule to allow a user to write to their own telephoneNumber property.
        PropertyAccessRule allowWritePhoneRule =
            new PropertyAccessRule(
                selfSid,
                AccessControlType.Allow,
                PropertyAccess.Write,
                phoneProperty.SchemaGuid,
                ActiveDirectorySecurityInheritance.Descendents,
                userClass.SchemaGuid);
        // Add the access rule to the DACL.
        container.ObjectSecurity.AddAccessRule(allowWritePhoneRule);
        // Commit the changes.
        container.CommitChanges();
    }
    catch (ActiveDirectoryObjectNotFoundException)
    {
        // The schema class or property could not be found.
    }
}
另请参见
参考
System.DirectoryServices
ActiveDirectorySecurity
ActiveDirectoryAccessRule
ActiveDirectoryAuditRule
概念
Send comments about this topic to Microsoft.
版权所有 (C) 2007 Microsoft Corporation。保留所有权利。