This article has been
excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors
of C# Corner.
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: 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: 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#.
|
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. |