Export (0) Print
Expand All

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)

public sealed class 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.

using System;
using System.Threading;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Runtime.InteropServices;
class SecurityContextSample
{
    static void Main()
    {
        try
        {
            Console.WriteLine("Executing the Main method in the primary " +
                "thread.");
            FileDialogPermission fdp = new FileDialogPermission(
                FileDialogPermissionAccess.OpenSave);
            fdp.Deny();
            // Do not allow the security context to pass across threads; 
            // suppress its flow.
            AsyncFlowControl aFC = SecurityContext.SuppressFlow();
            Thread t1 = new Thread(new ThreadStart(DemandPermission));
            t1.Start();
            t1.Join();
            Console.WriteLine("Is the flow suppressed? " +
                SecurityContext.IsFlowSuppressed());
            Console.WriteLine("Restore the flow.");
            aFC.Undo();
            Console.WriteLine("Is the flow suppressed? " +
                SecurityContext.IsFlowSuppressed());
            Thread t2 = new Thread(new ThreadStart(DemandPermission));
            t2.Start();
            t2.Join();
            CodeAccessPermission.RevertDeny();
            // Show the Deny is no longer present.
            Thread t3 = new Thread(new ThreadStart(DemandPermission));
            t3.Start();
            t3.Join();
            ImpersonateUser iU = new ImpersonateUser();
            iU.Impersonate();
            Thread t5 = new Thread(new ThreadStart(CheckIdentity));
            t5.Start();
            t5.Join();
            Console.WriteLine("Suppress the flow of the Windows identity.");
            AsyncFlowControl aFC2 =
                SecurityContext.SuppressFlowWindowsIdentity();
            Console.WriteLine("Has the Windows identity flow been suppressed?"
                + SecurityContext.IsWindowsIdentityFlowSuppressed());
            Thread t6 = new Thread(new ThreadStart(CheckIdentity));
            t6.Start();
            t6.Join();
            // Restore the flow of the Windows identity for the impersonated 
            // user.
            aFC2.Undo();
            Console.WriteLine("User name after restoring the Windows identity"
                + " flow with Undo: \n" + WindowsIdentity.GetCurrent().Name);
            iU.Undo();
            Console.WriteLine("This sample completed successfully;" +
                " press Enter to exit.");
            Console.Read();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    // Test method to be called on a second thread. 
    static void DemandPermission()
    {
        try
        {
            Console.WriteLine("This is the thread executing the " +
                "DemandPermission method.");
            new FileDialogPermission(
                FileDialogPermissionAccess.OpenSave).Demand();
            Console.WriteLine("FileDialogPermission was successsfully" +
                " demanded.");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

    static void CheckIdentity()
    {
        Console.WriteLine("Current user: " +
            WindowsIdentity.GetCurrent().Name);
    }

}
// Perform user impersonation. 
public class ImpersonateUser
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(
        String lpszUsername, 
        String lpszDomain, 
        String lpszPassword, 
        int dwLogonType, 
        int dwLogonProvider, 
        ref IntPtr phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public extern static bool DuplicateToken(
        IntPtr ExistingTokenHandle, 
        int SECURITY_IMPERSONATION_LEVEL, 
        ref IntPtr DuplicateTokenHandle);

    private static IntPtr tokenHandle = new IntPtr(0);
    private static IntPtr dupeTokenHandle = new IntPtr(0);
    private static WindowsImpersonationContext impersonatedUser;

    // If you incorporate this code into a DLL, be sure to demand that it 
    // runs with FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public void Impersonate()
    {
        try
        {
            string userName, domainName;
            // 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.
            Console.Write("Enter the name of the domain to log on to: ");
            domainName = Console.ReadLine();

            Console.Write("Enter the logon name of the user that you wish to"
                + " impersonate on {0}: ", domainName);
            userName = Console.ReadLine();

            Console.Write("Enter the password for {0}: ", userName);

            const int LOGON32_PROVIDER_DEFAULT = 0;
            // Passing this parameter causes LogonUser to create a primary 
            // token. 
            const int LOGON32_LOGON_INTERACTIVE = 2;
            tokenHandle = IntPtr.Zero;
            // Call  LogonUser to obtain a handle to an access token. 
            bool returnValue = LogonUser(
                userName, 
                domainName, 
                Console.ReadLine(), 
                LOGON32_LOGON_INTERACTIVE, 
                LOGON32_PROVIDER_DEFAULT, 
                ref tokenHandle);

            Console.WriteLine("LogonUser has been called.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser call failed with error code : " +
                    ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            Console.WriteLine("Did LogonUser succeed? " + 
                (returnValue ? "Yes" : "No"));
            Console.WriteLine("Value of the Windows NT token: " + 
                tokenHandle);
            // Check the identity.
            Console.WriteLine("User name before the impersonation: " + 
                WindowsIdentity.GetCurrent().Name);

            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            impersonatedUser = newId.Impersonate();
            // Check the identity.
            Console.WriteLine("User name after the impersonation: " + 
                WindowsIdentity.GetCurrent().Name);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }
    }

    public void Undo()
    {
        impersonatedUser.Undo();
        // Check the identity.
        Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name);
        // Free the tokens. 
        if (tokenHandle != IntPtr.Zero)
            CloseHandle(tokenHandle);
    }
}

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

Community Additions

ADD
Show:
© 2015 Microsoft