The first and second articles in this series about .NET security covered the basics of .NET identity-based security, and showed you how to implement custom authentication and authorization schemes. In this last installment, you get the missing piece of the puzzle: Learn how to implement identity flow and identity impersonation across.NET-distributed multilayered applications.

Like this article? We recommend

Like this article? We recommend

The first and second articles in this series covered the basics of .NET
identity based security and showed you how to implement custom authentication
and authorization schemes. In this last installment, we examine the issues
related to identity flow and identity impersonation across.NET-distributed
multilayered applications.

Identity Flow

As explained in the first article of this series, the .NET Framework keeps
identity- and role-related information in the running thread's
CurrentPrincipal property. Once this property has been set, typically during the
authentication phase, the .NET Framework propagates it along the thread's
execution flow and uses it to perform access checks when required. However, a
modern application often consists of different pieces of software distributed on
more than one machine following the classic three-tiered distributed application
pattern (Presentation tier, Business tier, Data tier).

In this situation, the logicalthread of execution
accomplishing a given application task may spawn across different processes and
computer boundaries. Evidently, one needs mostly to have the caller identity
flow across process and machine, so that a server executing some work on behalf
of the client will do it under the caller identity.

Although this is possible in .NET, unfortunately the way you do it varies
with the technology used for remote objects/services invocation: ASP.NET/Web
Services, .NET Remoting, and DCOM.

Regarding identity flow, the WindowsIdentity object deserves special
consideration. It can't be serialized because it points to Windows'
private, process-specific data structures. As a consequence, you must obey
Windows rules to transport a valid WindowsIdentity object from the client to the
server (more on this later).

Once you manage to transfer the caller identity to the server, you have two
options:

Simply attach the WindowsIdentity to the thread's CurrentPrincipal
to execute only .NET-specific access checks. However, in this case, Windows will
continue to use the server process identity when the resources that the OS is
aware of are accessed.

Switch to the caller identity at the Windows level as well, so that even
OS-protected resources will be access-checked using the client identity. This is
called impersonation.

When you avoid impersonation, you basically state that the application will
take care of access checks without delegating them to the OS or downstream
services such as databases. In this case, you typically configure the server
processes (application servers, Web servers) so they are granted the super set
of permissions (OS, file ACL, database permissions) required by the application
to execute the whole of its functionalities.