This documentation is archived and is not being maintained.

SecurityContext Class

Encapsulates and propagates all security-related data for execution contexts transferred across threads. This class cannot be inherited.

Namespace:  System.Security
Assembly:  mscorlib (in mscorlib.dll)

'Declaration
Public NotInheritable Class SecurityContext
'Usage
Dim instance As SecurityContext

A SecurityContext object captures all security-related information for a logical thread, including the information contained in the WindowsIdentity and CompressedStack objects. This configuration allows the Windows identity and the security elements on the stack to be propagated automatically when the SecurityContext is copied and transferred across asynchronous threads.

NoteNote:

The common language runtime (CLR) is aware of impersonation operations performed using only managed code, not of impersonation performed outside of managed code, such as through platform invoke to unmanaged code or through direct calls to Win32 functions. Only managed WindowsIdentity objects can flow across asynchronous points, unless the alwaysFlowImpersonationPolicy element has been set to true (<alwaysFlowImpersonationPolicy enabled="true"/>). Setting the alwaysFlowImpersonationPolicy element to true specifies that the Windows identity always flows across asynchronous points, regardless of how impersonation was performed. For more information on flowing unmanaged impersonation across asynchronous points, see <alwaysFlowImpersonationPolicy> Element.

The SecurityContext is part of the larger ExecutionContext and flows or migrates when the ExecutionContext flows or migrates.

The following code example shows the use of members of the SecurityContext class.

Imports System
Imports System.Threading
Imports System.Security
Imports System.Security.Permissions
Imports System.Security.Principal
Imports System.Runtime.InteropServices
Module Module1

    Sub Main()

        Try
            Console.WriteLine("Executing the Main method in the primary thread.")
            Dim fdp As New FileDialogPermission( _
                FileDialogPermissionAccess.OpenSave)
            fdp.Deny()
            Dim sC As Security.SecurityContext
            sC = Security.SecurityContext.Capture()

            ' Do not allow the security context to pass across threads; 
            ' suppress its flow. 
            Dim aFC As AsyncFlowControl
            aFC = Security.SecurityContext.SuppressFlow()
            Dim t1 As New Thread(New ThreadStart(AddressOf DemandPermission))
            t1.Start()
            t1.Join()

            Console.WriteLine("Is the flow suppressed? " & _
                Security.SecurityContext.IsFlowSuppressed())
            Console.WriteLine("Restore the flow.")
            aFC.Undo()
            Console.WriteLine("Is the flow suppressed? " & _
                Security.SecurityContext.IsFlowSuppressed())
            Dim t2 As New Thread(New ThreadStart(AddressOf DemandPermission))
            t2.Start()
            t2.Join()
            CodeAccessPermission.RevertDeny()
            Dim iU As New ImpersonateUser()
            iU.Impersonate()
            Dim t5 As New Thread(New ThreadStart(AddressOf CheckIdentity))
            t5.Start()
            t5.Join()
            Console.WriteLine("Suppress the flow of the Windows identity.")

            Dim aFC2 As AsyncFlowControl
            aFC2 = Security.SecurityContext.SuppressFlowWindowsIdentity()
            Console.WriteLine("Has the Windows identity flow been suppressed? " & _
                Security.SecurityContext.IsWindowsIdentityFlowSuppressed())
            Dim t6 As New Thread(New ThreadStart(AddressOf CheckIdentity))
            Console.WriteLine("Starting the second thread.")
            t6.Start()
            t6.Join()

            Console.WriteLine("Returned from the second thread.")
            ' Restore the flow of the Windows identity for the impersonated 
            ' user.
            aFC2.Undo()
            WriteLine("User name after restoring the Windows identity flow: ")
            WriteLine(WindowsIdentity.GetCurrent().Name)
            Console.WriteLine("Undo the impersonation.")
            iU.Undo()
        Catch ex As Exception
            WriteLine(ex.Message)
        End Try 

        ' Align interface and conclude application.
        WriteLine(vbCrLf + "This sample completed successfully;" + _
            " press Exit to continue.")

    End Sub 
    ' Test method to be called on a second thread. 
    Sub DemandPermission()
        Try
            Console.WriteLine("Executing the DemandPermission method from a" & _
                "seperate thread")
            Dim fDP As New FileDialogPermission( _
                FileDialogPermissionAccess.OpenSave)
            fDP.Demand()
            Console.WriteLine("FileDialogPermission was successsfully demanded.")
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try 
    End Sub 

    Sub CheckIdentity()
        Console.WriteLine("Current user: " & WindowsIdentity.GetCurrent().Name)
    End Sub 
    Public Class ImpersonateUser

        Declare Auto Function LogonUser Lib "advapi32.dll" ( _
            ByVal lpszUsername As String, _
            ByVal lpszDomain As String, _
            ByVal lpszPassword As String, _
            ByVal dwLogonType As Integer, _
            ByVal dwLogonProvider As Integer, _
            ByRef phToken As IntPtr) As Boolean

        Declare Auto Function CloseHandle Lib "kernel32.dll" ( _
            ByVal handle As IntPtr) As Boolean

        Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
            ByVal ExistingTokenHandle As IntPtr, _
            ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
            ByRef DuplicateTokenHandle As IntPtr) As Boolean 

        Private Shared tokenHandle As New IntPtr(0)
        Private Shared dupeTokenHandle As New IntPtr(0)
        Private Shared impersonatedUser As WindowsImpersonationContext

        ' If you incorporate this code into a DLL,  
        ' be sure to demand that it runs with FullTrust.
        <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
        Public Sub Impersonate()
            Try 
                Dim userName, domainName As String 
                ' Use the unmanaged LogonUser function to get the user token for 
                ' the specified user, domain, and password. 
                ' To impersonate a user on this machine, use the local machine 
                ' name for the domain name.
                domainName = InputBox("Enter the name of the domain to log on to")
                userName = InputBox("Enter the logon name of the user that " + _
                    "you wish to impersonate on " + domainName)

                Const LOGON32_PROVIDER_DEFAULT As Integer = 0
                ' Passing this parameter causes LogonUser to create a primary 
                ' token. 
                Const LOGON32_LOGON_INTERACTIVE As Integer = 2
                tokenHandle = IntPtr.Zero
                ' Call  LogonUser to obtain a handle to an access token. 
                Dim returnValue As Boolean = LogonUser( _
                    userName, _
                    domainName, _
                    InputBox("Enter the password for " + userName), _
                    LOGON32_LOGON_INTERACTIVE, _
                    LOGON32_PROVIDER_DEFAULT, _
                    tokenHandle)

                If (returnValue) Then 
                    Dim outputMessage As String
                    outputMessage = ("User successfully logged on!" + vbCrLf)
                    outputMessage += ("Windows NT token value: ")
                    outputMessage += (tokenHandle.ToString() + vbCrLf)
                    outputMessage += ("User name before impersonation: ")
                    outputMessage += (WindowsIdentity.GetCurrent().Name + vbCrLf)

                    Dim newId As New WindowsIdentity(tokenHandle)
                    impersonatedUser = newId.Impersonate()
                    outputMessage += ("User name after the impersonation: ")
                    outputMessage += (WindowsIdentity.GetCurrent().Name + vbCrLf)
                    MsgBox(outputMessage)
                Else 
                    Dim ret As Integer = Marshal.GetLastWin32Error()
                    Throw New System.ComponentModel.Win32Exception(ret)
                End If 
            Catch ex As Exception
                MsgBox("LogonUser call failed Exception occurred. " & ex.Message)
            End Try 
        End Sub 

        Public Sub Undo()
            impersonatedUser.Undo()
            ' Check the identity.
            MsgBox("User name restored to : " + _
                WindowsIdentity.GetCurrent().Name)
            ' Free the tokens. 
            If tokenHandle <> IntPtr.Zero Then
                CloseHandle(tokenHandle)
            End If 
        End Sub 
    End Class 


End Module

System.Object
  System.Security.SecurityContext

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0
Show: