Security


The CLR's security system provides two different security models: role-based security and evidence-based security. The role-based security system is based on the concepts of identity and roles, which represent the same abstractions that users and groups do in traditional operating system security. The evidence-based security system is based on the code (rather than the user executing the code) and is designed to provide security for mobile and downloaded code. This section discusses both security models, although more space is devoted to evidenced-based security because this model of security is newer to most developers.

In general, the following discussion and samples are based on the default settings for the security system within the CLR. Almost every aspect of the security system can be configured by administrators, but this reconfiguration of the security settings and their subsequent effects are well beyond the scope of this book.

Role-Based Security

As noted earlier, role-based security utilizes the concepts of identities and roles, which are similar to the notions of users and groups in many current operating systems. Two core abstractions in role-based security are the Identity and the Principal. An Identity represents the user on whose behalf the code is executing; it could be a logical user as defined by the application or developer, rather than the user as seen by the operating system. A Principal represents the abstraction of a user and the roles in which he or she belongs. Classes representing a user's Identity implement the IIdentity interface. A generic class providing a default implementation of this interface within the Framework Class Library is GenericIdentity . Classes representing Principals implement the IPrincipal interface. A generic class providing a default implementation of this interface within the FCL is GenericPrincipal .

At runtime, each thread has one and only one current Principal object associated with it. Code may, of course, access and change this object, subject to security requirements. Each Principal has one and one only Identity object. Logically, the runtime structure of the objects resembles Figure 4.2.

Figure 4.2. Runtime structure under role-based security

graphics/04fig02.gif

Listing 4.3 demonstrates how developers can use the generic classes. This program demonstrates how to set and test for different identities and roles. In this case, the developer supplies the security model, the name "Damien"; the roles "Author" and "Speaker" are not tied to any user or roles that the operating system may support.

Listing 4.3 Generic classes under role-based security
 using System; using System.Threading; using System.Security; using System.Security.Principal; namespace RoleBasedSecurity {   class Sample   {     static void Main(string[] args)     {       String [] roles = {"Author", "Speaker"};       GenericIdentity i = new GenericIdentity("Damien");       GenericPrincipal g = new GenericPrincipal(i, roles);       Thread.CurrentPrincipal = g;       if(Thread.CurrentPrincipal.Identity.Name == "Damien")         Console.WriteLine("Hello Damien");       if(Thread.CurrentPrincipal.IsInRole("Author"))         Console.WriteLine("Hello Author");       if(Thread.CurrentPrincipal.IsInRole("Publisher"))         Console.WriteLine("Hello Publisher");     }   } } 

Listing 4.3 produces the following output:

 Hello Damien  Hello Author 

You can also use the Windows security model. In this situation, users and roles are tied to those on the hosting machine, so the developer may need to create accounts on the hosting system. Listing 4.4 uses the local machine's user accounts. This program demonstrates how to limit access to methods based on the user's identity. The example also includes some "syntactic sugar": The BCL's PrincipalPermissionAttribute effectively encapsulates the calls to methods such as IsInRole to allow developers to use a simplified syntax.

Listing 4.4 Role-based Windows security
 using System; using System.Security.Permissions; using System.Security.Principal; namespace RoleBased {   class Sample   {     [PrincipalPermissionAttribute(SecurityAction.Demand,                     Name=@"PROJECT42\Damien Watkins")]     public static void UserDemandDamien()     {       Console.WriteLine("Hello Damien!");     }     [PrincipalPermissionAttribute(SecurityAction.Demand,                     Name=@"PROJECT42\Dean Thompson")]     public static void UserDemandDean()     {     Console.WriteLine("Hello Dean!");     }     static void Main(string[] args)     {       AppDomain.CurrentDomain.SetPrincipalPolicy(                     PrincipalPolicy.WindowsPrincipal);       try       {         UserDemandDamien();         UserDemandDean();       }       catch(Exception)       {         Console.WriteLine("Exception thrown");       }     }   } } 

The PrincipalPermissionAtribute ensures that a runtime check occurs each time the program calls the methods UserDemandDamien and UserDemandDean . Naturally, the program can be executed by Dean or Damien or someone else, so the security check should fail on at least one of the two method calls, if not both. The first line of Main sets the Principal policy to that employed by Windows, the operating system on which this example was executed. Listing 4.4 produces the following output when executed by the user "PROJECT42\Damien Watkins":

 Hello Damien!  Exception thrown 

Evidence-Based Security

Essentially, evidence-based security assigns permissions to assemblies based on evidence. It uses the location from which executable code is obtained as a primary factor in determining which resources the code should be able to access. Whenever an assembly is loaded into the CLR for execution, the hosting environment attaches a number of pieces of evidence to the assembly. The security system in the CLR must then map this evidence into a set of permissions, which will determine the code's access to a number of resources.

Permissions

Permissions represent authorization to perform operations, many of which require access to a resource. In general, an operation may involve accessing resources such as files, the Registry, the network, the user interface, or the execution environment. An example of a permission that does not involve a tangible resource is the ability to skip verification. The fundamental abstraction of a permission is the IPermission interface.

A permission grant represents the authority to perform an action that has been granted to an assembly based on the evidence presented to the security system when it was loaded. A permission demand triggers a security check to see whether a specific permission has been granted; if the demand fails, then an exception is raised.

The class System.Security.PermissionSet represents a collection of permissions. Methods on this class include Intersect and Union , which take another PermissionSet as a parameter and provide a PermissionSet that is either the union or intersection of all permissions in both sets. With these facilities, the security system can work with permissions sets and not have to understand the semantics of each individual type of permission. This flexibility allows developers to extend the permission hierarchy without modifying any of the security engine's functionality.

Evidence

Whenever an assembly is loaded into the CLR, the hosting environment presents the security system with evidence related to it. A number of types of evidence exist:

  • Zone: The same concept as zones used in Internet Explorer.

  • URL: A specific URL or file location that identifies a specific resource, such as http://www.aw.com/catalog/academic/product/1,4096,0201770180,00.html .

  • Hash: The hash value of an assembly generated with algorithms such as SHA1.

  • Strong name: The use of digital signing with hashing.

  • Site: The site from which the code came. A URL is more specific than the notion of a site; for example, www.aw.com is a site.

  • Application directory: The directory from which the code is loaded.

  • Publisher certificate: The use of digital signatures, such as Authenticode.

As noted above, the concept of zones is similar to that used in Internet Explorer. A zone may be any of the following (note that the default permissions are listed here):

  • The My Computer zone (see the output from Listing 4.5 later in

  • The My Computer zone (see the output from Listing 4.5 later in this section) is for executables run from the local hard disk; these programs often receive the most powerful permission sets.

  • The Local Intranet zone represents executables run from a local intranet. These programs are less trusted than code from the local hard disk so, for example, they cannot access the Registry.

  • The Internet zone represents code executed from the Internet. It has limited resources available during execution.

  • The Trusted Sites zone includes a specified list of trusted sites. By default, this kind of zone executes with the same capabilities as the Internet zone.

  • The Untrusted Sites zone includes a specified list of untrusted sites. Applications from these sites cannot be executed.

Administrators may reconfigure the permissions listed above as they see fit. For example, it is not immediately obvious why both an Internet zone and a Trusted Sites zone exist, given that they receive the same permission sets. In this case, the distinction makes sense only if administrators actually do reconfigure the settings.

Both strong names and publisher certificates constitute assembly-based evidence; in other words, they are carried within the assembly. The hosting environment provides all other evidence.

Example: Passing Evidence to the CLR Security System

Listing 4.5 provides a simple example of the evidence passed to the CLR security system when an assembly is loaded. In this case, mscorlib is the loaded assembly; it contains many of the CLR types, such as Object and String .

Listing 4.5 Evidence-based security
 using System; using System.Collections; using System.Reflection; using System.Security.Policy; namespace AssemblyEvidence {   class EntryPoint   {     static void Main(string[] args)     {       Type t = typeof(System.String);       Assembly a = Assembly.GetAssembly(t);       Evidence e = a.Evidence;       IEnumerator i = e.GetEnumerator();       while(i.MoveNext())         Console.WriteLine(i.Current);     }   } } 

The output from Listing 4.5 shows the evidence passed to the security system; it has been edited for brevity. The security system takes this evidence and produces a permission set for the assembly.

 <System.Security.Policy.Zone version="1">     <Zone>MyComputer</Zone> </System.Security.Policy.Zone> <System.Security.Policy.Url version="1">    <Url>file://C:/windows/microsoft.net/framework/    v1.0.3705/mscorlib.dll</Url> </System.Security.Policy.Url> <StrongName version="1"             Key="00000000000000000400000000000000"             Name="mscorlib"             Version="1.0.3300.0"/> <System.Security.Policy.Hash version="1">    <RawData>4D5A90000300000004000000FFFF0000B800000000000    00040000000000      ...      0000000000000000000000000000000000000000000000000000    </RawData> </System.Security.Policy.Hash> 

As an aside, many aspects of the security system, as well as many parts of the .NET Framework, use eXtended Markup Language (XML) as a fundamental means of describing data. Developers using the CLR are strongly advised to explore its design and use.



Programming in the .NET Environment
Programming in the .NET Environment
ISBN: 0201770180
EAN: 2147483647
Year: 2002
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net