获取当前登录用户的组相当容易。有几种不同的方法,但这可能是最简单的:
UserPrincipal.Current.GetAuthorizationGroups()
这将递归地获取用户所属的所有安全组 - 因此,如果用户是组 A 的成员,并且该组在组 B 中,您将在此列表中看到组 B。 (实际上我写了一篇文章,讨论了该方法的工作原理:Finding all of a user’s groups)
然后您只需通过查看列表中组的Name 属性来检查您想要的组是否存在。
如果您发现这太慢了,可以使用一种更快但不太友好的方法来实现。用户的身份验证令牌包含其组的所有 SID(这实际上是 GetAuthorizationGroups() 使用的),但它仅包含 SID。所以GetAuthorizationGroups() 会去 AD 并获取每一个的属性(每组一个网络请求)。
为了避免网络流量(和时间),您可以使用以下命令直接查看 SID:
System.Security.Principal.WindowsIdentity.GetCurrent().Groups
这将返回SecurityIdentifier 的列表。如果您存储正在使用的组的 SID,而不是名称,那么您可以将其与 SecurityIdentifier 的 Value 进行比较,您可以在不联系 AD 的情况下完成整个操作。
更新:所有这些都将帮助您确定用户是否在您想要的组中(域管理员?)。如果您想为用户提供输入不同凭据的选项,那么……您可以通过多种方式来实现。
我认为最简单的方法是创建您自己的接受用户名和密码的对话框,并使用solution here 使用新凭据重新启动您的应用程序(转换为 VB.NET):
Dim proc As System.Diagnostics.Process = New System.Diagnostics.Process()
proc.StartInfo.UseShellExecute = False
proc.StartInfo.FileName = Application.ExecutablePath
proc.StartInfo.Domain = "domainname"
proc.StartInfo.UserName = "username"
'Translate the user-entered String into a SecureString
'If you take the password as a SecureString in the first place
'you won't have to do this
Dim password As String = "user entered password"
Dim ssPwd As System.Security.SecureString = New System.Security.SecureString()
For x As Integer = 0 To password.Length - 1
ssPwd.AppendChar(password(x))
Next
proc.StartInfo.Password = ssPwd
proc.Start()
Application.Exit()
请注意,documentation on the UserName property 表示:
如果您使用 UPN 格式 user@DNS_domain_name,则域属性必须为 null。
因此您可能需要检查用户是否给了您DOMAIN\Username 或Username@domain.com 并适当地分配UserName 和Domain 属性。