在我自己的C#控件中使用Flags,例如Active Directory中UserAccountControl中的设置

时间:2010-10-31 03:19:07

标签: c# active-directory class-design bitarray

我在涉及Active Directory的项目中使用System.DirectoryServices一段时间了。我很好奇UserAccountControl属性的实现,以控制特定帐户的属性。如果我想使用字节组合在我自己的应用程序中实现设置来确定x或y设置的状态,我将如何在C#中执行此操作?说我想实现一个在我自己的类上使用useraccountcontrol属性,我想使用字节组合来确定帐户应该具有哪些权限。

以下是在Active Directory中修改它的方式: http://support.microsoft.com/kb/305144

这里是对象定义的地方: http://msdn.microsoft.com/en-us/library/ms680832%28VS.85%29.aspx

编辑:

假设我有自己的User类,并且我想实现类似于在Active Directory中实现UserAccountControl的方式的属性。假设我想要一组存储设置的四个字节。

我想使用最后一个字节来确定帐户状态, 0 =帐户无效1 =帐户有效2 =帐户已过期4 =某些其他状态8 =另一种状态。

然后左边的下一个字节我要包含帐户类型: 16 =管理员帐户,32 =普通帐户,64 =访客帐户,128 =其他帐户。

然后使用左边的下一个字节来设置其他设置 256 =某事,512 =其他东西,1024 =其他东西,等等。

我想将此组合使用按位组合来设置帐户属性。我有这个想法,但我不知道如何实现它,或者它是否有意义我想要做什么。

编辑: 在收到答案并进行更多挖掘后,我发现这个链接更多地谈到了设置Flags:http://msdn.microsoft.com/en-us/library/ms229062.aspx

1 个答案:

答案 0 :(得分:1)

让我们定义一个帮助者类型:

[Flags]
public enum UserAccountControl {
    // values from http://support.microsoft.com/kb/305144
    Script = 0x0001,
    AccountDisabled = 0x0002,
    HomeDirRequired = 0x0008,
    Lockout = 0x0010,
    PasswordNotRequired = 0x0020,
    PasswordCantChange = 0x0040,
    EncryptedTextPasswordAllowed = 0x0080,
    TempDuplicateAccount = 0x0100,
    NormalAccount = 0x0200,
    InterDomainTrustAccount = 0x0800,
    WorkstationTrustAccount = 0x1000,
    ServerTrustAccount = 0x2000,
    DontExpirePassword = 0x10000,
    MnsLogonAccount = 0x20000,
    SmartcardRequired = 0x40000,
    TrustedForDelegation = 0x80000,
    Delegated = 0x100000,
    UseDesKeyOnly = 0x200000,
    DontReqPreauth = 0x400000,
    PasswordExpired = 0x800000,
    TrustedToAuthForDelegation = 0x1000000
}

您可以在intenum类型之间进行转换(我假设您知道如何将这些值中的一个作为整数)。然后,您可以使用按位运算符操作值,如下所示:

void manipulateUserFlags(UserAccountControl uac) {
    // Set the SCRIPT flag (bitwise OR)
    uac |= UserAccountControl.Script;

    // Clear the ACCOUNTDISABLE flag (complement, bitwise AND)
    uac &= ~UserAccountControl.AccountDisabled;

    // Check for the HOMEDIR_REQUIRED flag (bitwise AND)
    if((uac & UserAccountControl.HomeDirRequired) != UserAccountControl.None) {
        // ...
    }

    // Toggle the NORMAL_ACCOUNT flag (bitwise XOR)
    uac ^= UserAccountControl.NormalAccount;

    // Check for several types of trust, and a required password
    if((uac & UserAccountControl.WorkstationTrustAccount
            & UserAccountControl.ServerTrustAccount
            & ~UserAccountControl.PasswordNotRequired) != UserAccountControl.None) {
        // ...
    }
}

这些是用于整数的相同的按位运算符,但在C#中建议使用enum类型,因为它们的类型更强。在C或C ++中,对整数的按位操作更有意义,因为你可以直接测试条件中的整数,因为这些语言不是那么强类型。

但是,如果您要将其作为库的一部分实现,或者通常执行这些操作,我会考虑在其周围添加更多设计,并使用几个基于enum的属性来表示组类似的设置,以及int ToADValueUserAccountControl FromADValue方法。这将为您提供一个放置任何验证逻辑的明确位置,并且它将使操作这些属性的代码更具可读性。