This article addresses the security aspects of assemblies, which are the
building blocks of .NET Framework applications. They form the fundamental unit
of deployment, version control, reuse, activation scope, and security
authorization. This last aspect, security authorization, is the focal point of
this article.
Microsoft took a big stride toward improved configuration and maintenance of
software systems by allowing administrators rather than developers to determine
the permissions a segment of code should have at runtime. Now such decisions
fall under the domain of professionals who really know the runtime environment.
During installation of a new application in the Windows Operating System (OS),
the setup package may overwrite existing shared dynamic-link libraries (DLLs) to
update the module. (Of course, well-designed installation programs prompt you
about duplicate file names.) The overwriting occurs because you cannot have
multiple versions of DLLs in a shared environment. This often causes existing
applications to function incorrectly because they may depend on a specific
version of the shared DLL, which may have been overwritten! The most recently
installed version of the shared DLL can overwrite a previously installed yet
more current version. The version most recently installed prevails for all of
the installed applications referencing that DLL module, potentially causing
enormous problems for administrators.
The C# compiler processes your source code and produces Microsoft intermediate
language (MSIL) assembly files. Additionally, it embeds metadata in your
assemblies. The .NET metadata is merely a cluster of information, specifically,
the declared types, methods, fields, properties, and events implemented in the
files of the assembly, made persistent in binary data. The metadata is always
embedded in the same executable file and DLL as the MSIL code. For example, the
metadata contains reference data to find the actual code for every implemented
method that the common language runtime (CLR) uses.
Not surprisingly, in the .NET Framework, assemblies are also versioned like DLLs
that are based on the Component Object Model (COM). However, multiple versions
of an assembly can coexist on the same computer without causing trouble. This
allows applications to run with the assemblies they were built with. Assemblies
contain all the metadata related to them, so no separate files are necessary to
describe the contents of an assembly.
As with COM+, the .NET Framework code that accesses computing resources must be
assigned permission to use those resources. The system administrator can
configure security policies to grant access to resources based on the caller's
identity and the origin of the code. For example, suppose you develop code that
accesses any registry key. At execution time, the framework requests Security in
.NET 711 IUnknown IInterface1 permission to access the registry. This way the
system can make sure that the assembly in which the executed program exists has
permission to access the registry key.
Formerly, all applications installed on a computer had to be registered before
they could be used. Most installation programs not only copy files to the
computer but also add various information to the registry and create various
hard settings needed to uninstall that application later.
It is safe to say that we have reached the end of the COM+ era and the beginning
of the .NET era. With the advent of .NET Framework, we no longer need to develop
COM+ components unless they are truly necessary in order to interact with legacy
applications. Of course, we will still use legacy COM+ components with our
current Web services and other .NET applications during the migration to .NET
applications.
Figure 22.1 depicts the typical way of exposing a COM+ component interface via
the .NET framework. You can use any .NET client application, such as a Web
service in which the .NET client application itself is a server application, to
expose the component interface. In other words, the .NET client application (Web
service) is an intermediary application to the actual COM+ component or server.
Figure 22.1: Client Access Through Runtime Callable Wrapper
The runtime callable wrapper (RCW) of .NET wraps the COM+ components' exposed
interfaces. The RCW mediates between the COM+ component and the CLR. RCW exposes
the COM+ components to .NET clients as if they were native .NET components. RCW
exposes the .NET clients to COM+ components as if they were standard COM
clients.
As a .NET client developer, you can generate the RCW using either Visual Studio
.NET (VS.NET) or the command-line-based type library import utility of the .NET
software development kit (SDK). With the VS.NET approach, you add a COM+
reference to your active project; with the .NET SDK approach, you use a
command-line tool called tlbimp.exe.
To install an application within the .NET Framework, you just copy the
application's files into a directory on the client computer. There are two
assembly types in .NET: private and public. You usually copy the private
assemblies to the application installation directory. Any subfolder within the
installation directory is also an appropriate place for private assemblies. You
can uninstall private assemblies by deleting them from the local directory. You
install shared public assemblies either to the global assembly cache (GAC) or to
another global location on the computer disk. When any client application wants
to reference and use those classes in a public (shared) or private assembly, it
consults its configuration files to locate and then load the shared or private
assembly. If the desired assembly cannot be found in the client application's
configuration files, the application has the option of searching the system's
configuration files.
The manifest information cluster is the most significant part of an assembly.
The manifest of an assembly contains the following metadata information: