Show Changes Show Changes
Edit Edit
Print Print
Recent Changes Recent Changes
Subscriptions Subscriptions
Lost and Found Lost and Found
Find References Find References
Rename Rename
Search

History

8/26/2004 6:41:21 AM
List all versions List all versions
What Is Security Context
.

To put it simply, a security context is a bit of cached data about a user, including her SID, group SIDs, privileges, and some other stuff that I'll cover in WhatIsAToken. One of the fundamental tenets of Windows security is that each process runs on behalf of a user, so each process has a security context associated with it, like a global variable controlled by the kernel. This allows the system to audit the actions taken by a process and make access control decisions when the process acquires resources.

To be more precise, a process is just a container, and it's really threads that do things, such as open resources. But unless you're impersonating (which I'll discuss in WhatIsImpersonation), all the threads in your process are by default associated with the process’s security context.

In Windows, a security context is represented by a data structure called a token. Each process object in the kernel holds a handle to an associated token object in the kernel. In this marriage, there's no option for divorce; once a process starts, it's associated with the same token for its entire lifetime.

The ability of a token to cache a snapshot of a user's security profile is critical for performance. But a cache is like a loaf of bread; the longer you keep it, the more stale it gets. A process that runs for a week has a security context that's at least a week old. If the user was recently added to or removed from a group, even a local one, the process won't know about it. And simply recycling the process isn't going to help because the operating system initializes each new process with a copy of the creator's token. To get a fresh security context, you must establish a fresh logon; in technical terms, you must reauthenticate. The latency caused by a stale security context can bite you not only in a long running desktop application but also in a server application that caches security contexts for each authenticated client that it services. Keep this in mind when designing your systems. You might occasionally need to throw away a client's moldy old token and ask her to reauthenticate, for example.

When building a desktop application, you should think about the different security contexts in which the app may run. Today it might be running with high privilege and be able to (heaven forbid) write data files in sensitive directories like Program Files; tomorrow, however, it may be running with low privilege. You should be sure to test your app under different security contexts, and make sure it doesn't fall to pieces when run by a normal user, as discussed in HowToDevelopCodeAsANonAdmin.

Server applications are very different. A server application normally runs as a daemon (see HowToGetATokenForAUser), and it has a well-defined security context that it needs to function. For example, a service is configured to run under a particular identity and, no matter who starts that service, the Service Control Manager (SCM) ensures that it's started in the security context with which it was configured to run. The designer and developer of a server application should know exactly what privileges (WhatIsAPrivilege), roles (WhatIsRoleBasedSecurity), and permissions (WhatIsACLBasedSecurity) the server app requires. This should be part of the documentation for the application, as it will allow an administrator to choose an appropriate identity for the server process (as opposed to simply running it as SYSTEM) and configure security policy to allow access to required resources. Note that these requirements may be different depending on which features of the server application are in use. Keep track of your requirements as you go, and document them carefully. Don't wait until the project is over to try and figure this stuff out.

Another difference with a server application is that it's normally juggling several security contexts at once. Each authenticated client presents its security context to the server (often in the form of a token), which must make security decisions based on the client's context. This is one of the most confusing things about security for newbies. Just remember that when a new client connects to your server, it doesn't change the server’s security context. The server continues to run under its own preconfigured identity. It may choose to temporarily impersonate a client (WhatIsImpersonation) before accessing a resource, but that's its prerogative. Further food for thought on client authorization schemes can be found in WhatIsRoleBasedSecurity and WhatIsACLBasedSecurity. To learn more about how servers authenticate their clients in Windows, see WhatIsKerberos.

Security Context in the .NET Framework

The .NET Framework doesn't limit itself to representing users only via tokens. Instead, two interfaces abstract security context: IIdentity and IPrincipal, which allows for a broad range of authentication options beyond those

        namespace System.Security.Principal {
          public interface IIdentity {
            bool IsAuthenticated      { get; }
            string AuthenticationType { get; }
            string Name               { get; }
          }
          public interface IPrincipal {
            bool IsInRole(string role);
            IIdentity Identity { get; }
          }
        }

that Windows happens to implement natively. For instance, you can roll your own user database and use Forms Authentication in ASP.NET to authenticate users. In that case, you'll end up representing your clients not with tokens but with a simpler security context (in the simplest case, just a user name) that you help define. The roles simply become strings that you assign based on your own security database. With the notion of identity and roles so abstract, any code you write that makes demands of your clients, such as requiring authentication or membership in some role, can do so without being tied to any one form of authentication.

You might wonder why two interfaces are used to represent this one idea of security context. I like to think of it this way: IIdentity deals with authentication (Who are you?), whereas IPrincipal deals with authorization (What are you allowed to do?). This decoupling can be very convenient. For example, you can allow Windows to do the heavy lifting by authenticating your clients using Kerberos (WhatIsKerberos), and then take the resulting IIdentity and drop it behind your own custom implementation of IPrincipal. In this way you can add a set of application-specific roles that are populated based on the user's group memberships (as shown in Figure 15.1). To make authorization decisions in your code, it's better to check for an application-defined role than for a Windows group. This is because each group name includes the name of the domain or machine where the group was defined (say, SALESDOMAIN\Customers), and if you've hardcoded names like these into your code, you're tightly coupled to that environment (what if you wanted to deploy your program in two domains?). See WhatIsAuthorizationManager for a role-based approach to authorization that can help solve problems like these.

Figure 15.1 Customizing roles by implementing IPrincipal yourself

As you'll see in WhatIsAToken, when a token is providing the security context, WindowsIdentity and WindowsPrincipal provide concrete implementations for these interfaces.

PortedBy JohnScanlon

PluralsightTraining

Keith's first book-in-a-wiki. If you would like to read the book online or order a physical copy to throw at annoying coworkers, surf to the HomePage. Please note that due to overwhelming wikispam, this particular wiki is no longer editable.

About FlexWiki.

Recent Topics