【问题标题】:Determining a User's Group Membership确定用户的组成员身份
【发布时间】:2009-01-06 15:00:15
【问题描述】:

如何确定用户(例如 Access)是否是 Active Directory 安全组的成员?

我宁愿不在我的小 Access DB 中构建一个完整的身份验证系统。

谢谢

【问题讨论】:

    标签: vba security ms-access


    【解决方案1】:

    找到阿兰this online

    Function IsMember(strDomain As String, strGroup _
      As String, strMember As String) As Boolean
      Dim grp As Object
      Dim strPath As String
    
      strPath = "WinNT://" & strDomain & "/"
      Set grp = GetObject(strPath & strGroup & ",group")
      IsMember = grp.IsMember(strPath & strMember)
    End Function
    

    您可以通过USERDOMAINUSERNAME 环境变量获取Windows 帐户信息:

    Function GetCurrentUser() As String
        GetCurrentUser = Environ("USERNAME")
    End Function
    
    Function GetCurrentDomain() As String
        GetCurrentDomain = Environ("USERDOMAIN")
    End Function
    

    把它们放在一起:

    If IsMember(GetCurrentDomain, "AD Group", GetCurrentUser) Then
       DoStuff()
    End If
    

    【讨论】:

    • 是的。它主要用于向不同的用户显示不同的屏幕。与其说是安全,不如说是可用性。
    • 这个答案与 AD 无关——它只是普通的旧 NTFS 组。 AD 有诸如组织单位之类的东西,它们不是 NTFS 的一部分,只能通过 LDAP 查询访问。
    • 我建议不要将环境变量用于用户名和用户域:它们是本地设置,可以更改。查询 Windows 网络会询问 Active Directory 和 Domain Server 你是谁以及你在哪里,这更可靠一些。
    • 详细说明 Nigels 的评论,GetCurrentUser = CreateObject("WScript.Network").Username GetCurrentDomain = CreateObject("WScript.Network").UserDomain
    【解决方案2】:

    我迟到了,但您需要的代码如下。它会为您获取用户名和域名。

    请注意,我没有使用 objGroup.Ismember - 这实际上是正确的使用方法 - 我正在枚举用户所在的组列表,因为它更容易调试并且没有明显的性能损失。

    ...我从早期项目中提取了代码,在该项目中我需要检查“读取报告”组、“编辑数据”组和“编辑系统数据”组的成员资格,以便我可以选择启用哪些控件以及以只读方式打开哪些表单。枚举组一次比三个单独的检查要快。

    Public Function UserIsInGroup(GroupName As String, _
                                  Optional Username As String, _
                                  Optional Domain As String) As Boolean
    'On Error Resume Next
    
    ' Returns TRUE if the user is in the named NT Group.
    
    ' If user name is omitted, current logged-in user's login name is assumed.
    ' If domain is omitted, current logged-in user's domain is assumed.
    ' User name can be submitted in the form 'myDomain/MyName' 
    '                                        (this will run slightly faster)
    ' Does not raise errors for unknown user.
    '
    ' Sample Usage: UserIsInGroup( "Domain Users")
    
    Dim strUsername As String
    Dim objGroup    As Object
    Dim objUser     As Object
    Dim objNetwork  As Object
    
    UserIsInGroup = False
    
    If Username = "" Then
        Set objNetwork = CreateObject("WScript.Network")
        strUsername = objNetwork.UserDomain & "/" & objNetwork.Username
    Else
        strUsername = Username
    End If
    
    strUsername = Replace(strUsername, "\", "/")
    If InStr(strUsername, "/") Then
        ' No action: Domain has already been supplied in the user name
    Else    
        If Domain = "" Then
            Set objNetwork = CreateObject("WScript.Network")
            Domain = objNetwork.UserDomain
        End If        
        strUsername = Domain & "/" & strUsername        
    End If
    
    Set objUser = GetObject("WinNT://" & strUsername & ",user")    
    If objUser Is Nothing Then    
        ' Insert error-handler here if you want to report an unknown user name
    Else
        For Each objGroup In objUser.Groups
            'Debug.Print objGroup.Name
            If GroupName = objGroup.Name Then
                UserIsInGroup = True
                Exit For
            End If
        Next objGroup
    End If
    
    Set objNetwork = Nothing
    Set objGroup = Nothing
    Set objUser = Nothing
    
    End Function
    

    希望这个迟到的提交对其他开发人员有用:当我第一次查找这个时,早在 2003 年,就好像没有人在 Excel 或 MS-Access 中使用过 AD 组。

    【讨论】:

    • 记录一下,这在2017年还是蛮有用的。:)
    • 需要注意的一点:如果您的用户拥有由不同时区的多台服务器管理的组成员资格——我为客户工作,而对于在两个或更多办公室拥有个人资料的员工来说,情况就是如此——您会发现遍历所有组将需要几秒钟。在这些情况下 objGroup.Ismember 是要走的路。我会敦促您不要使用用户组列表的本地缓存,但是当您需要反复检查时可能会很诱人,因为这是非常糟糕的安全做法。
    • 在 2019 年仍然有用:D 谢谢@NigelHeffernan
    • 如何获取用户是否包含在嵌套组中?
    • @Luis - 嵌套组更难:您需要枚举并递归搜索嵌套组结构。
    【解决方案3】:

    找到this online

    Function IsMember(strDomain As String, strGroup _
      As String, strMember As String) As Boolean
      Dim grp As Object
      Dim strPath As String
    
      strPath = "WinNT://" & strDomain & "/"
      Set grp = GetObject(strPath & strGroup & ",group")
      IsMember = grp.IsMember(strPath & strMember)
    End Function
    

    现在,我只需要当前用户的帐户名。太糟糕了Application.CurrentUser 没有给我他们的域帐户名称。

    【讨论】:

    • 只是一个警告。此代码将为用户主要组(通常为“域用户”)返回不正确的结果,因为它在 AD 中的存储方式不同。
    • 没问题。在 12 月底,我已经与这个问题作斗争了几个星期,并且通过艰难的方式学习了其中的大部分内容。对于此类问题,我强烈推荐一本书:“.NET 开发人员目录服务编程指南”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 2017-11-06
    • 2021-11-28
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    相关资源
    最近更新 更多