将UserName转换为WindowsIdentity?

时间:2014-02-23 23:43:07

标签: c# .net vb.net admin user-accounts

我已使用C#标记了此问题,因为它是.NET的一部分,众所周知,有些人可以编程并理解VB.NET和{{1} }作为一个,我不应该将C#指令翻译成C#,然后我会对使用其中一种语言编写的解决方案感到满意。


我想在此函数中指定一个用户名来检索它是否为管理员,我应该做哪些更改?

VB.NET

PS:当然MsgBox(UserIsAdmin("Elektro")) ' ByVal UserName as String or other needed object. Public Function UserIsAdmin(ByVal UserName As XXXX) As Boolean Dim Identity As Security.Principal.WindowsIdentity = Security.Principal.WindowsIdentity.FromUserName(UserName) Return New Security.Principal.WindowsPrincipal(Identity). IsInRole(Security.Principal.WindowsBuiltInRole.Administrator) End Function 方法不存在。


  

更新

我只是尝试@meziantou方法,但我总是得到一个关于用户名结构的例外或关于网络条目没有找到,但是,无论如何,这不是我正在寻找的(我的意思是指定一个域名)或计算机名称或其他任何未通过该功能自动完成的事情。)

FromUserName

  

更新2

我正在尝试@Frinavale方法,但我无法调整此代码来检索我感兴趣的信息。

Public Class Form

Private Sub Test() Handles MyBase.Shown

    ' Things that I've tried:

    MsgBox(UserIsAdmin("Administrador")) ' Username
    MsgBox(UserIsAdmin("Administrador@127.0.0.1")) ' Username@LocalHost
    MsgBox(UserIsAdmin(Security.Principal.WindowsIdentity.GetCurrent().Name)) ' DomainName\Username
    MsgBox(UserIsAdmin("Administrador@ELEKTRO")) ' Username@DomainName
    MsgBox(UserIsAdmin(Security.Principal.WindowsIdentity.GetCurrent.User.Value)) ' The SID

End Sub

''' <summary>
''' Determines whether an user is an Administrator.
''' </summary>
''' <returns><c>true</c> if the user is an Administrator, <c>false</c> otherwise.</returns>
Public Function UserIsAdmin(Optional ByVal UserName As String = String.Empty) As Boolean

    Dim Identity As Security.Principal.WindowsIdentity =
        If(Not String.IsNullOrEmpty(UserName),
           New Security.Principal.WindowsIdentity(UserName),
           Security.Principal.WindowsIdentity.GetCurrent())

    Return New Security.Principal.WindowsPrincipal(Identity).
               IsInRole(Security.Principal.WindowsBuiltInRole.Administrator)

End Function

End Class

3 个答案:

答案 0 :(得分:3)

您可以使用GroupPrincipal Class检索属于管理员组的所有用户。拥有所有成员后,您可以通过将成员的名称与提供的用户名进行比较来确定用户是否在该组中。

例如:

Public Function UserIsAdmin(ByVal userName As String) As Boolean
        Dim groupName As String = "administrators" '<--You can localize this'
        Dim isAdmin As Boolean
        Using context As PrincipalContext = New PrincipalContext(ContextType.Machine)
            Dim gfilter As GroupPrincipal = GroupPrincipal.FindByIdentity(context, groupName)
            If gfilter IsNot Nothing Then
                Dim members = gfilter.GetMembers
                For Each member In members
                    If String.Compare(member.Name, userName, True) = 0 Then
                        isAdmin = True
                    End If
                Next
            End If
        End Using
        Return isAdmin
End Function

我知道您提到该组的名称已本地化(由于我使用的是美国英语操作系统/环境,因此我没有这样做)。在这种情况下,我建议您查看Globalization的主题(将“管理员”的本地化版本存储到资源文件中,密钥为“administrators”,然后根据“管理员”检索“管理员”的相应文本。你工作的文化)

答案 1 :(得分:2)

要从用户名获取WindowsIdentity,您可以使用WindowsIdentity构造函数(http://msdn.microsoft.com/en-us/library/td3046fc(v=vs.110).aspx

Dim windowsIdentity = New WindowsIdentity("administrator")
New WindowsPrincipal(windowsIdentity).IsInRole(WindowsBuiltInRole.Administrator)

答案 2 :(得分:1)

MSDN说WindowsIdentity对象只能是一个已登录的用户,所以似乎无法进行我想要的用户名转换,但是,这是一个有效的解决方案:

' User Is Admin?
'
' Instructions:
' 1. Add a reference to 'System.DirectoryServices.AccountManagement'.
' 2. Imports System.DirectoryServices.AccountManagement
'
' Example Usages:
' MsgBox(UserIsAdmin("Administrador"))
' MsgBox(UserIsAdmin(New Security.Principal.SecurityIdentifier("S-1-5-21-250596608-219436059-1115792336-500")))
'
''' <summary>
''' Determines whether an User is an Administrator, in the current machine.
''' </summary>
''' <param name="UserName">Indicates the account Username.</param>
''' <returns><c>true</c> if user is an Administrator, <c>false</c> otherwise.</returns>
Public Function UserIsAdmin(ByVal UserName As String) As Boolean

    Dim AdminGroupSID As New SecurityIdentifier("S-1-5-32-544")

    Dim pContext As New PrincipalContext(ContextType.Machine)
    Dim pUser As New UserPrincipal(pContext)
    Dim pSearcher As New PrincipalSearcher(pUser)

    Dim User As Principal =
        (From u As Principal In pSearcher.FindAll
        Where u.Name.Equals(UserName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault

    If User Is Nothing Then
        Throw New Exception(String.Format("User with name '{0}' not found.", UserName))
    End If

    Dim IsAdmin As Boolean =
        (From Group As GroupPrincipal In User.GetGroups
         Where Group.Sid = AdminGroupSID).Any

    pContext.Dispose()
    pSearcher.Dispose()
    pUser.Dispose()

    Return IsAdmin

End Function
相关问题