从本地计算机关闭网络确定用户Active Directory组

我当前的项目要求我针对Active Directory组validation用户。 问题是,计算机可能并不总是连接到域,但用户可能仍需要运行该工具。 我知道我没有连接时无法查询Active Directory,而是在尝试查询机器SAM(MSAM)。

我在断开网络连接时无法确定当前用户。 这是我正在使用的:

PrincipalContext principalctx = new PrincipalContext(ContextType.Machine); UserPrincipal uprincipal = new UserPrincipal(principalctx); 

从这一点开始,我如何询问当前登录本地计算机的用户。

当连接到域时,我可以使用UserPrincipal.Current进行查询。 如果我没有连接到域,它将无法说"The server could not be contacted" 。 注意:使用上面的代码不能使用此方法,而是可以放弃PrincipalContext并直接查询当前用户。 在识别出当前用户的情况下,我可以查询GetGroups()并确定它们是否在所需的组中。

此外,有人可以描述三个ContextType选项ApplicationDirectory, Domain, Machine 。 我担心我不完全理解每个选项,因此可能使用不正确。

从一开始:

我当前的项目要求我针对Active Directory组validation用户。 问题是,计算机可能并不总是连接到域,但用户可能仍需要运行该工具。

此时,您必须接受攻击者可以绕过任何强制安全性,因为它完全在客户端上强制执行。 不完全是解决方案的一部分,但请记住。

我知道我没有连接时无法查询Active Directory,而是在尝试查询机器SAM(MSAM)。

安全帐户管理器仅存储本地帐户(MACHINENAME \ Administrator和其他)。 它不具有域用户凭据。 您正在考虑LSA缓存 ,它记住最后N个域登录的凭据(其中N是组策略配置的0到50之间的数字)和最后N SID命名映射(默认为128, 可通过注册表配置 )。 安全帐户管理器仅在域控制器上存储域帐户。

我在断开网络连接时无法确定当前用户。 这是我正在使用的:PrincipalContext principalctx = new PrincipalContext(ContextType.Machine); UserPrincipal uprincipal = new UserPrincipal(principalctx);

此外,有人可以描述三个ContextType选项ApplicationDirectory,Domain,Machine。 我担心我不完全理解每个选项,因此可能使用不正确。

如上所述,信息不会被缓存,但ContextType枚举可以描述如下:

来自MSDN:

  • 域:域存储。 这代表AD DS存储。 (正如它所说,这适用于域帐户,如在Active Directory的LDAP目录访问中 – 这需要网络访问)
  • ApplicationDirectory:应用程序目录存储。 这代表AD LDS商店。 ( AD轻量级目录服务 (以前称为ADAM)是Active Directory的较小版本,旨在存储单个应用程序的凭据。它与此讨论无关,但也使用LDAP。)
  • 机器:电脑商店。 这代表SAM商店。 (仅列举本地帐户)

从这一点开始,我如何询问当前登录本地计算机的用户。

您始终可以通过调用WindowsIdentity.GetCurrent()来检查登录用户。 如果在脱机时发生登录,这将返回登录用户的SID和组SID(可能已缓存)。

当连接到域时,我可以使用UserPrincipal.Current进行查询。 如果我没有连接到域,它将无法说“无法联系服务器”。 注意:使用上面的代码不能使用此方法,而是可以放弃PrincipalContext并直接查询当前用户。 在识别出当前用户的情况下,我可以查询GetGroups()并确定它们是否在所需的组中。

要确定组成员身份,请检查所需的组的SID是否在WindowsIdentity.GetCurrent返回的标识中。 如果您未在Access Control系统中使用SID,则可以通过调用SecurityIdentifier.Translate将名称转换为SID。 您需要在线时进行翻译,然后将其缓存以供离线使用。 它可以存储为字符串或二进制文件,因此两者都适合注册表。

 // while we are online, translate the Group to SID // Obviously, administrators would be a bad example as it is a well known SID... var admins = new NTAccount("Administrators"); var adminSid = (SecurityIdentifier)admins.Translate(typeof(SecurityIdentifier)); // store the sid as a byte array on disk somewhere byte[] adminSIDbytes = new byte[adminSid.BinaryLength]; adminSid.GetBinaryForm(adminSIDbytes, 0); // at time of check, retrieve the sid and check membership var sidToCheck = new SecurityIdentifier(adminSIDbytes, 0); if (!wi.Groups.Contains(sidToCheck)) throw new UnauthorizedAccessException("User is not a member of required group"); 

另一个案例:

  • 如果要使用PrincipalContext获取网络域名,请确保validation了身份validation和授权。 如下所示: 获取网络域名