System.Security.Principal using VB.NET: Part 2
In this article I will explain you about System.Security.Principal in VB.NET.
See Part 1
Impersonate and ImpersonateContext
If your application must impersonate a Windows account that has not been attached to the current thread, you must retrieve that account's token and use it to activate the account:
-
Retrieve an account token for a particular user by making a call to the unmanaged LogonUser method, passing it the user name, password, and domain of the account you want. This method is not in the .NET Framework base class library but is located in the unmanaged advapi32.dll library. For the LogonUser call to work, a special privilege known as SE_TCB_NAME is needed. You can check this by selecting Control Panel?Administrative Tools?Local Security Policy Settings.
-
Create a new instance of the WindowsIdentity class, passing the account token retrieved in the preceding step.
-
Begin impersonation by creating a new instance of the WindowsImpersonationContext class and initializing it with the Impersonate method of the WindowsIdentity object created in the preceding step.
-
When you no longer need to impersonate the Windows user, call the WindowsImpersonationContext.Undo method to revert the impersonation with MyImpersonation.Undo().
Listing 22.29 illustrates how you can accomplish impersonation.
Listing 22.29: Impersonation Example
' impersonation
Public Class ImpersonationExample
<DllImport("ADVAPI32")> _
Private Shared Function LogonUser(ByVal lpszUsername As [String], ByVal lpszDomain As [String], ByVal
lpszPasswords As [String], ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, ByVal phToken As (InPtr) As Integer
End Function
Public Sub anyfunction()
Dim lToken As InPtr
Dim lRetVal__1 As Integer = 0
lRetval = LogonUser(strUserName, strDomain, strPassword, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, lToken)
If lRetval = 0 Then
Console.WriteLine("Login error occurred!")
Return
End If
Dim ImpId As New WindowsIdentity(lToken)
Dim ImpContext As WindowsImpersonationContext = ImpId.Impersonate()
' you are impersonating another user now in this
' thread!
' execute some managed and unmanaged code now
ImpContext.Undo()
End Sub
Listing 22.30 creates two PrincipalPermission objects representing two different users. The union demand succeeds only if user mcb is in the role of director or user mindcracker is in the role of officer.
Listing 22.30: PrincipalPermission Union Example
' Union Demand
Dim id1 As [String] = "mcb"
Dim role1 As [String] = "Director"
Dim PrincipalPerm1 As New PrincipalPermission(id1, role1)
Dim id2 As [String] = "mindcracker"
Dim role2 As [String] = "Officer"
Dim PrincipalPerm2 As New PrincipalPermission(id2, role2)
(PrincipalPerm1.Union(PrincipalPerm2)).Demand()
In Listing 22.31, the current WindowsIdentity class is transformed into a WindowsPrincipal class. Then all of the identity and principal properties are written to the system console.
Listing 22.31: WindowsIdentity to WindowsPrincipal Example
' WindowsIdentity illustrated
Dim MyIdentity As WindowsIdentity = WindowsIdentity.GetCurrent()
Dim MyPrincipal As New WindowsPrincipal(MyIdentity)
'Principal values.
Console.WriteLine(MyPrincipal.Identity.Name)
Console.WriteLine(MyPrincipal.Identity.AuthenticationType)
Console.WriteLine(MyPrincipal.Identity.IsAuthenticated.ToString())
'Identity values.
Console.WriteLine(MyIdentity.Name)
Console.WriteLine(MyIdentity.AuthenticationType)
Console.WriteLine(MyIdentity.IsAuthenticated.ToString())
Console.WriteLine(MyIdentity.IsAnonymous.ToString())
Console.WriteLine(MyIdentity.IsGuest.ToString())
Console.WriteLine(MyIdentity.IsSystem.ToString())
Console.WriteLine(MyIdentity.Token.ToString())
Listing 22.32 illustrates GenericIdentity class usage.
Listing 22.32: GenericIdentity Example
DirectCast(AppDomain.CurrentDomain.SetPrincipalPolicy, PrincipalPolicy.WindowsPrincipal)
Dim myUser As WindowsPrincipal = DirectCast(System.Threading.Thread.CurrentPrincipal, WindowsPrincipal)
Dim MyIdentity As New GenericIdentity(myUser.Identity.Name.ToString())
Dim MyStringArray As [String]() = {"Role1", "Teller"}
Dim MyPrincipal As New GenericPrincipal(MyIdentity, MyStringArray)
System.Threading.Thread.CurrentPrincipal = MyPrincipal
'Return user values
Dim Name As [String] = MyPrincipal.Identity.Name
Dim Auth As Boolean = MyPrincipal.Identity.IsAuthenticated
Dim IsInRole As Boolean = MyPrincipal.IsInRole("Role2")
If IsInRole Then
Console.WriteLine("The test was successful as a user in the user-defined role of Role1")
Else
Console.WriteLine("The test was not successful!")
End If
In Listing 22.33, declarative demands for PrincipalPermission and PrincipalPermissionAttribute are illustrated. The attribute adjustment says that only a principal in the role of Role1 may execute these functions.
Listing 22.33: Declarative Identity Example
<PrincipalPermission(SecurityAction.Demand, Role:="Role1")> _
Private Function MyFunction() As String
Return "Declarative control for the role of Role1 is truly successfully. his function can be executed by you!"
End Function
<PrincipalPermissionAttribute(SecurityAction.Demand, Name:="MyUser", Role:="Role1")> _
Public Shared Sub PrivateInfo()
'Output of private data
Console.WriteLine("You have access to the private data!")
End Sub
Conclusion
Hope this article would have helped you in understanding System.Security.Principal in VB.NET.