简体   繁体   English

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

[英]Determine User Active Directory Groups from Local Machine off Network

My current project requires that I validate a user against Active Directory groups. 我当前的项目要求我针对Active Directory组验证用户。 The catch is, the computer may not always be connected to the domain but users may still need to run the tool. 问题是,计算机可能并不总是连接到域,但用户可能仍需要运行该工具。 I understand that I can't query Active Directory while I'm not connected, instead I'm trying to query the Machine SAM (MSAM). 我知道我没有连接时无法查询Active Directory,而是在尝试查询机器SAM(MSAM)。

I am having trouble determining the current user while I'm disconnected from the network. 我在断开网络连接时无法确定当前用户。 Here's what I'm using: 这是我正在使用的:

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

From this point, how do I ask who is currently logged into the local machine. 从这一点开始,我如何询问当前谁登录到本地计算机。

When connected to the domain, I can query using UserPrincipal.Current . 当连接到域时,我可以使用UserPrincipal.Current进行查询。 If I am not connected to the domain it will fail saying "The server could not be contacted" . 如果我没有连接到域,它将无法说"The server could not be contacted" Note: this method is not available using the above code, instead I can forgo the PrincipalContext and directly query the current user. 注意:使用上面的代码不能使用此方法,而是可以放弃PrincipalContext并直接查询当前用户。 With the current user identified I can query GetGroups() and determine if they're in one of the required groups. 在识别出当前用户的情况下,我可以查询GetGroups()并确定它们是否在所需的组中。

Also, can someone please describe the three ContextType options ApplicationDirectory, Domain, Machine . 此外,有人可以描述三个ContextType选项ApplicationDirectory, Domain, Machine I'm afraid I don't fully understand each option and therefore may be using it incorrectly. 我担心我不完全理解每个选项,因此可能使用不正确。

From the top: 从顶部:

My current project requires that I validate a user against Active Directory groups. 我当前的项目要求我针对Active Directory组验证用户。 The catch is, the computer may not always be connected to the domain but users may still need to run the tool. 问题是,计算机可能并不总是连接到域,但用户可能仍需要运行该工具。

At this point, you must therefore accept that any enforced security is able to be bypassed by an attacker since it is entirely enforced on the client. 此时,您必须接受攻击者可以绕过任何强制安全性,因为它完全在客户端上强制执行。 Not exactly part of the solution, but keep it in mind. 不完全是解决方案的一部分,但请记住。

I understand that I can't query Active Directory while I'm not connected, instead I'm trying to query the Machine SAM (MSAM). 我知道我没有连接时无法查询Active Directory,而是在尝试查询机器SAM(MSAM)。

The Security Accounts Manager only stores the local accounts (MACHINENAME\\Administrator and others). 安全帐户管理器仅存储本地帐户(MACHINENAME \\ Administrator和其他)。 It will not have domain user credentials. 它不具有域用户凭据。 You are thinking of the LSA cache , which remembers the last N domain logins's credentials (where N is a number from 0 to 50 as configured by Group Policy) and the last N SID to name mappings (defaults to 128, configurable via registry ). 您正在考虑LSA缓存 ,它记住最后N个域登录的凭据(其中N是组策略配置的0到50之间的数字)和最后N SID命名映射(默认为128, 可通过注册表配置 )。 The Security Accounts Manager only stores domain accounts on a domain controller. 安全帐户管理器仅在域控制器上存储域帐户。

I am having trouble determining the current user while I'm disconnected from the network. 我在断开网络连接时无法确定当前用户。 Here's what I'm using: PrincipalContext principalctx = new PrincipalContext(ContextType.Machine); 这是我正在使用的:PrincipalContext principalctx = new PrincipalContext(ContextType.Machine); UserPrincipal uprincipal = new UserPrincipal(principalctx); UserPrincipal uprincipal = new UserPrincipal(principalctx);

Also, can someone please describe the three ContextType options ApplicationDirectory, Domain, Machine. 此外,有人可以描述三个ContextType选项ApplicationDirectory,Domain,Machine。 I'm afraid I don't fully understand each option and therefore may be using it incorrectly. 我担心我不完全理解每个选项,因此可能使用不正确。

As noted above, information is not cached, but the ContextType enum can be described as follows: 如上所述,信息不会被缓存,但ContextType枚举可以描述如下:

From MSDN: 来自MSDN:

  • Domain: The domain store. 域:域存储。 This represents the AD DS store. 这代表AD DS存储。 (As it says, this is for domain accounts, as in LDAP Directory access of Active Directory - which would require network access) (正如它所说,这适用于域帐户,如在Active Directory的LDAP目录访问中 - 这将需要网络访问)
  • ApplicationDirectory: The application directory store. ApplicationDirectory:应用程序目录存储。 This represents the AD LDS store. 这代表AD LDS商店。 ( AD Lightweight Directory Services (previously known as ADAM) is a smaller version of Active Directory designed to store credentials for a single application. It is not relevant to this discussion, but also uses LDAP.) AD轻量级目录服务 (以前称为ADAM)是Active Directory的较小版本,旨在存储单个应用程序的凭据。它与此讨论无关,但也使用LDAP。)
  • Machine: The computer store. 机器:电脑商店。 This represents the SAM store. 这代表SAM商店。 (Enumerates local accounts only) (仅列举本地帐户)

From this point, how do I ask who is currently logged into the local machine. 从这一点开始,我如何询问当前谁登录到本地计算机。

You can always examine the logged on user by calling WindowsIdentity.GetCurrent() . 您始终可以通过调用WindowsIdentity.GetCurrent()来检查登录用户。 This will return the logged in user's SID and Group SIDs, possibly cached, if the login occurred while offline. 如果在脱机时发生登录,这将返回登录用户的SID和组SID(可能已缓存)。

When connected to the domain, I can query using UserPrincipal.Current. 当连接到域时,我可以使用UserPrincipal.Current进行查询。 If I am not connected to the domain it will fail saying "The server could not be contacted". 如果我没有连接到域,它将无法说“无法联系服务器”。 Note: this method is not available using the above code, instead I can forgo the PrincipalContext and directly query the current user. 注意:使用上面的代码不能使用此方法,而是可以放弃PrincipalContext并直接查询当前用户。 With the current user identified I can query GetGroups() and determine if they're in one of the required groups. 在识别出当前用户的情况下,我可以查询GetGroups()并确定它们是否在所需的组中。

To determine group membership, check if the group's SID you want is in the identity returned by WindowsIdentity.GetCurrent . 要确定组成员身份,请检查所需的组的SID是否在WindowsIdentity.GetCurrent返回的标识中。 If you are not using the SID in your Access Control system, you can translate a name to an SID by calling SecurityIdentifier.Translate . 如果您未在Access Control系统中使用SID,则可以通过调用SecurityIdentifier.Translate将名称转换为SID。 You will need to translate it while online, then cache it for use offline. 您需要在线时进行翻译,然后将其缓存以供离线使用。 It is storable as either a string or as binary, so both fit well in the registry. 它可以存储为字符串或二进制文件,因此两者都适合注册表。

// 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");

Another case: 另一个案例:

  • If you want to use PrincipalContext to get Network Domain name, please make sure you verified authentication and authorization. 如果要使用PrincipalContext获取网络域名,请确保验证了身份验证和授权。 Like below : get Network Domain name 如下所示: 获取网络域名

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM