In a .NET 3.5 Winforms app, after a user provides a username and password, I set a custom principal in the CurrentPrincipal
property like this:
My.User.CurrentPrincipal = Service.GetPrincipal(username)
This is done in a method that is called using Invoke, because the originating thread is not the UI thread:
Invoke(New Action(AddressOf doLogin))
But when I click on a button in the Winforms application, the CurrentPrincipal property has been reverted to its default, the current Windows user.
Dim lPrincipal = My.User.CurrentPrincipal ' not my custom principal
Apparently, using Invoke while setting the principal does not solve the problem. Is there another way to set the CurrentPrincipal
property for all threads in the application?
Sourcecode to reproduce the problem:
Imports System.Security.Principal
Imports System.Threading
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim lThread As New Thread(AddressOf doLogin)
lThread.Start()
End Sub
Private Sub doLogin()
Invoke(New Action(AddressOf setPrincipal))
End Sub
Private Sub setPrincipal()
My.User.CurrentPrincipal = New CustomPrincipal
MsgBox(My.User.CurrentPrincipal.Identity.AuthenticationType) ' Custom
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MsgBox(My.User.CurrentPrincipal.Identity.AuthenticationType) ' Default
End Sub
End Class
Public Class CustomPrincipal
Implements IPrincipal
Public ReadOnly Property Identity() As IIdentity Implements IPrincipal.Identity
Get
Return New CustomIdentity()
End Get
End Property
Public Function IsInRole(ByVal role As String) As Boolean Implements IPrincipal.IsInRole
Return True
End Function
End Class
Public Class CustomIdentity
Implements IIdentity
Public ReadOnly Property AuthenticationType() As String Implements IIdentity.AuthenticationType
Get
Return "Custom"
End Get
End Property
Public ReadOnly Property IsAuthenticated() As Boolean Implements IIdentity.IsAuthenticated
Get
Return True
End Get
End Property
Public ReadOnly Property Name() As String Implements IIdentity.Name
Get
Return "CustomName"
End Get
End Property
End Class