Security Classes in .NET


This article has been excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors of C# Corner.

System.Security 

The System.Security namespace provides the underlying structure of the .NET Framework security system. It includes interfaces, attributes, exceptions, and base classes for permissions, as well as the CodeAccessPermission class, which defines the underlying structure of all code access permissions. 

IPermission Interface 

Many Permission classes implement the IPermission interface, which takes the form shown in Listing 22.12. 

Listing 22.12: IPermission Interface 

        interface IPermission
        {
            bool IsSubsetOf(IPermission target);
            void Demand();
            void DemandImmediate();
            IPermission Copy();
            IPermission Intersect(IPermission target);
            IPermission Union(IPermission target);
        }

ISecurityEncodable Interface 

The ISecurityEncodable interface is implemented to serialize permissions to and from XML format. Listing 22.13 shows the typical structure of the interface. 

Listing 22.13: ISecurityEncodable Interface 

        interface ISecurityEncodable
        {
            void FromXml(SecurityElement e);
            SecurityElement ToXml();
        }

Listing 22.14 provides an example of XML security serialization. 

Listing 22.14: XML Security Serialization 

            // code to show XML serialization
            PermissionSet ps = new PermissionSet(PermissionState.None);
            SecurityElement myDOM = ps.ToXml();
            Console.WriteLine(myDom.ToString());

Permission Classes 

All of the classes listed in Table 22.4 are derived from the CodeAccessPermission class. 

Table-22.4.gif

Table 22.4: Permission Classes in the System.Security Namespace 

Table 22.5 lists the most common methods used with the permission classes. Three of these methods-Assert, Deny, and PermitOnly-are called overrides because they override the default behavior of the security system. When different overrides are present in the same stack frame, the runtime processes these overrides in the following order: PermitOnly, Deny, and Assert

Table-22.5.gif

Table 22.5: Commonly Used Methods of Permissions Classes 

If, during the stack walk, the runtime discovers more than one override of the same type (e.g., two calls to Assert in one stack frame), the second override causes an exception. To replace an override, first call the appropriate revert method (e.g., RevertAssert) and then apply the new override. Also, be aware that each stack frame can have, at most, one permission set used for denial. The most recent Deny function replaces all other denials for other permission sets in the current stack frame. 

In Listing 22.15, a demand for a read operation to c:\dir1\ is called. If the system refuses that demand, an exception is thrown. 

Listing 22.15: Executing the Demand method of a Permissions object 

            // Demand
            try
            {
                FileIOPermission p = new FileIOPermission(FileIOPermissionAccess.Read,"C:\\dir1\\");
                p.Demand();
            }

            catch (SecurityException ex)
            {
                // catch SecurityException here
            }

The code in Listing 22.16 compares two file permissions to determine whether one is a subset of the other. If so, the subset may derive granted permissions from the "parent." For example, if file I/O permission to c:\dir1\ is granted, then file I/O permission to c:\dir1\dir2\ is also granted. Thus, you can conclude that perm2 is a subset of perm1 in this example. 

Listing 22.16: IsSubsetOf Example 

// IsSubsetOf tests
using System;
using System.Security;
using System.Security.Permissions;

class TestClass
{
    public static void Main()
    {
        try
        {
            // create two registry permissions
            RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.AllAccess,
            @"HKEY_LOCAL_MACHINE");
            RegistryPermission perm2 = new RegistryPermission(
            RegistryPermissionAccess.AllAccess,
            @"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\FloatingPointProcessor\0");

            // and test which is subset of which?
            Console.WriteLine(perm1.IsSubsetOf(perm2) ? "perm1 is subset of perm2." : "test1 not successful!");
            Console.WriteLine(perm2.IsSubsetOf(perm1) ? "perm2 is subset of perm1." : "test2 not successful!");
            /* The program will output:
            test1 not successful!
            perm2 is subset of perm1.
            */
        }

        catch (Exception e)
        {
            Console.WriteLine("SecurityException occurred! " + e.ToString());
        }
    }
}

Listing 22.17 illustrates a typical use of the Assert method. First, file I/O permission is demanded. Then the Assert method is called to affirm permission to unmanaged code. As a result, no more stack walk-ups are performed until processing of the unmanaged code is complete. 

Listing 22.17: Assert Example 

// assert unmanaged code
        try
        {
            FileIOPermission p1 = new FileIOPermission(
            FileIOPermissionAccess.Read, @"C:\dir1\");
            filePerm.Demand();
            SecurityPermission unmanagedPerm =
            new SecurityPermission(
            SecurityPermissionFlags.UnmanagedCode);
            unmanagedPerm.Assert();

            // call unmanaged code
        }

        catch
        {
            // demand for file I/O permission failed.
        }

Listing 22.18 uses the Demand and Assert methods together for performance tuning. First, you demand an environment variable for read permission. Then you assert that need and execute nonrisky code in terms of that environment permission. 

Listing 22.18: Demand and Assert Example 

        // demand and assert together
        try
        {
            EnvironmentPermission envPerm = new EnvironmentPermission(
            EnvironmentPermissionAccess.Read, "TEMP");
            // Demand it once to see if it has been granted.
            envPerm.Demand();
            // Assert the permission to stop the stack walk here.
            envPerm.Assert();

            for (int i = 0; i < 100; i++)
            {
                // code that reads TEMP environment variable
            }
        }

        catch
        {
            // The demand failed.
        }

SecurityAction Enumeration 

SecurityAction is an enumeration that encompasses the following elements:

  • LinkDemand
  • InheritanceDemand
  • Demand
  • Assert
  • Deny
  • PermitOnly
  • RequestMinimum
  • RequestOptional
  • RequestRefuse

SecurityPermissionFlag Enumeration 

The SecurityPermissionFlag enumeration helps to specify access flags for the security permission object. The SecurityPermission class uses this enumeration. Many of these flags are powerful and should be granted only to highly trusted code. 

The enumeration contains the following elements:

  • AllFlags
  • Assertion
  • ControlAppDomain
  • ControlDomainPolicy
  • ControlEvidence
  • ControlPolicy
  • ControlPrincipal
  • ControlThread
  • Execution
  • Infrastructure
  • NoFlags
  • RemotingConfiguration
  • SerializationFormatter
  • SkipVerification
  • UnmanagedCode

Listing 22.19 shows how to use the SecurityPermissionFlag enumeration to request minimum security in the class attributes. This causes security verification to be skipped during JIT compilation. 

Listing 22.19: SecurityPermissionFlag 

        // SecurityPermissionFlag
         [SecurityPermissionAttribute(SecurityAction.RequestMinimum,
        Flags =SecurityPermissionFlag.SkipVerification)]
        public class MySecureClass
        {
        public MySecureClass ()
        {
        // code here
        }
        }
        }

Conclusion

Hope this article would have helped you in understanding Security Classes in .NET. See other articles on the website on .NET and C#.

visual C-sharp.jpg
The Complete Visual C# Programmer's Guide covers most of the major components that make up C# and the .net environment. The book is geared toward the intermediate programmer, but contains enough material to satisfy the advanced developer.


Similar Articles