The System.Security.Permissions namespace is the namespace used in the code to establish and use permissions to access many things, such as the file system, environment variables, and the registry within your programs. The namespace controls access to both operating system−level objects as well as code objects. In order to use the namespace in your project, you need to include the Imports System.Security.Permissions line with any of your other Imports statements in your project. Using this namespace gives you access to the CodeAccessPermission and PrincipalPermission classes for using role-based permissions and utilizing information supplied by Identity permissions. CodeAccessPermission is the main class that we will use, as it controls access to the operating system−level objects our code needs in order to function. Role-based permissions and Identity permissions grant access to objects based on the identity that the user of the program that is running carries with them (the user context).
In the following table, classes that end with Attribute, such as EnvironmentPermissionAttribute, are classes that enable you to modify the security level at which your code is allowed to interact with each respective object. The attributes that you can specify reflect either Assert, Deny, or PermitOnly permissions.
If permissions are asserted, you have full access to the object, whereas if you have specified Deny permissions you are not allowed to access the object through your code. If you have PermitOnly access, only objects within your program’s already determined scope can be accessed, and you cannot add any more resources beyond that scope. The table also deals with security in regard to software publishers. A software publisher is a specific entity that is using a digital signature to identify itself in a Web-based application. The following is a table of the namespace members that apply to Windows Forms programming, with an explanation of each:
Class | Description |
---|---|
CodeAccessSecurityAttribute | Specifies security access to objects such as the registry and file system |
EnvironmentPermission | Controls the ability to see and modify system and user environment variables |
EnvironmentPermissionAttribute | Allows security actions for environment variables to be added via code |
FileDialogPermission | Controls the ability to open files via a file dialog |
FileDialogPermissionAttribute | Allows security actions to be added for file dialogs via code |
FileIOPermission | Controls the capability to read and write files in the file system |
FileIOPermissionAttribute | Allows security actions to be added for file access attempts via code |
GacIdentityPermission | Defines the identity permissions for files that come from the global assembly cache (GAC). This is a new class in the .NET Framework 2.0. |
GacIdentityPermissionAttribute | Allows security actions to be added for files that originate from the GAC |
IsolatedStorageFilePermission | Controls access to a private virtual file system within the isolated storage area of an application |
IsolatedStorageFilePermission Attribute | Allows security actions to be added for private virtual file systems via code |
IsolatedStoragePermission | Controls access to the isolated storage area of an application |
IsolatedStoragePermission Attribute | Allows security actions to be added for the isolated storage area of an application |
KeyContainerPermission | Controls access to key containers. This is a new class in the .NET Framework 2.0. |
KeyContainerPermissionAccess Entry | Defines the access rights for particular key containers |
KeyContainerPermissionAccess EntryCollection | Represents a collection of KeyContainerPermission - AccessEntry objects |
KeyContainerPermissionAccess EntryEnumerator | Represents the enumerators for the objects contained in the KeyContainerPermissionAccessEntryCollection object |
KeyContainerPermissionAttribute | Allows security actions to be added for key containers |
PermissionSetAttribute | Allows security actions to be added for a permission set |
PrincipalPermission | Controls the ability to make checks against an active principal |
PrincipalPermissionAttribute | Allows for checking against a specific user. Security principals are a user and role combination used to establish security identity. |
PublisherIdentityPermission | Allows access based on the identity of a software publisher |
PublisherIdentityPermission Attribute | Allows security actions to be added for a software publisher |
ReflectionPermission | Controls access to nonpublic members of a given type |
ReflectionPermissionAttribute | Allows for security actions to be added for public and nonpublic members of a given type |
RegistryPermission | Controls access to registry keys and values |
RegistryPermissionAttribute | Allows security actions to be added for registry keys and values |
ResourcePermissionBase | Controls the ability to work with the code access security permissions |
ResourcePermissionBaseEntry | Allows you to define the smallest part of a code access security permission set |
SecurityAttribute | Controls which security attributes are representing code; used to control the security when creating an assembly |
SecurityPermission | The set of security permission flags for use by .NET; this collection is used when you want to specify a permission flag in your code |
SecurityPermissionAttribute | Allows security actions for the security permission flags |
StorePermission | Controls access to stores that contain X509 certificates. This is a new class in the .NET Framework 2.0. |
StorePermissionAttribute | Allows security actions to be added for access stores that contain X509 certificates |
UIPermission | Controls access to user interfaces and use of the Windows clipboard |
UIPermissionAttribute | Allows security actions to be added for UI interfaces and the use of the clipboard |
Code access permissions are controlled through the CodeAccessPermission class within the System .Security namespace, and its members make up the majority of the permissions we’ll use in our attempt to secure our code and operating environment. The following table describes the class methods available:
Method | Description |
---|---|
Assert | Sets the permission to full access so that the specific resource can be accessed even if the caller hasn’t been granted permission to access the resource |
Copy | Copies a permission object |
Demand | Returns whether or not all callers in the call chain have been granted the permission to access the resource in a given manner |
Deny | Denies all callers access to the resource |
Equals | Determines whether a given object is the same instance of the current object |
FromXml | Establishes a permission set given a specific XML encoding. This parameter is an XML encoding |
GetHashCode | Returns a hash code associated with a given object |
GetType | Returns the type of a given object |
Intersect | Returns the permissions that two permission objects have in common |
IsSubsetOf | Returns a result indicating whether the current permission object is a subset of a specified permission |
PermitOnly | Specifies that only those resources within this permission object can be accessed even if code has been granted permission to other objects |
RevertAll | Reverses all previous assert, deny or permit-only methods |
RevertAssert | Reverses all previous assert methods |
RevertDeny | Reverses all previous deny methods |
RevertPermit-Only | Reverses all previous permit-only methods |
ToString | Returns a string representation of the current permission object |
ToXml | Creates an XML representation of the current permission object |
Union | Creates a permission that is the union of two permission objects |
Role-based permissions are permissions granted based on the user and the role that code is being called with. Users are generally authenticated within the operating system platform and hold a Security Identifier (SID) that is associated within a security context. The SID can further be associated with a role or a group membership that is established within a security context. The .NET role functionality supports those users and roles associated within a security context and has support for generic and custom users and roles through the concept of principals. A principal is an object that holds the current caller credentials, which is termed the identity of the user. Principals come in two types: Windows principals and non-Windows principals. Windows-based principal objects are objects that store the Windows SID information regarding the current user context associated with the code that is calling into the module role-based permissions that are being used. Non-Windows principals are principal objects that are created programmatically via a custom login methodology and which are made available to the current thread.
Role-based permissions are not set against objects within your environment like code access permissions. They are instead a permission that is checked within the context of the current user and role that a user is part of. Within the System.Security.Permissions namespace, the concept of the principals and the PrincipalPermission class of objects are used to establish and check permissions. If a programmer passes the user and role information during a call as captured from a custom login, then the PrincipalPermission class can be used to verify this information as well. During the verification, if the user and role information is Null, then permission is granted, regardless of the user and role. The PrincipalPermission class does not grant access to objects, but has methods that determine whether a caller has been given permissions according to the current permission object through the Demand() method. If a security exception is generated, then the user does not have sufficient permission.
The following table describes the methods in the PrincipalPermission class:
Method | Description |
---|---|
Copy | Copies a permission object |
Demand | Returns whether or not all callers in the call chain have been granted the permission to access the resource in a given manner |
Equals | Determines whether a given object is the same instance of the current object |
FromXml | Establishes a permission set given a specific XML encoding |
GetHashCode | Returns a hash code associated with a given object |
GetType | Returns the type of a given object |
Intersect | Returns the permissions that two permission objects have in common specified in the parameter |
IsSubsetOf | Returns a result indicating whether the current permission object is a subset of a specified permission |
IsUnrestricted | Returns a result indicating whether the current permission object is unrestricted |
ToString | Returns a string representation of the current permission object |
ToXml | Creates an XML representation of the current permission object |
Union | Creates a permission that is the union of two permission objects |
As an example of how you might use these methods, the following code snippet captures the current Windows principal information and displays it on the screen in the form of message box output. Each element of the principal information could be used in a program to validate against, and thus restrict, code execution based on the values in the principal information. This example inserts an Imports System.Security.Principal line at the top of the module so you can use the identity and principal objects:
Imports System.Security.Principal Imports System.Security.Permissions Private Sub RoleBasedPermissions_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles RoleBasedPermissions.Click Dim objIdentity As WindowsIdentity = WindowsIdentity.GetCurrent Dim objPrincipal As New WindowsPrincipal(objIdentity) MessageBox.Show(objPrincipal.Identity.IsAuthenticated.ToString()) MessageBox.Show(objIdentity.IsGuest.ToString()) MessageBox.Show(objIdentity.ToString()) objIdentity = Nothing objPrincipal = Nothing End Sub
This code illustrates a few of the properties that could be used to validate against when a caller wants to run your code. Sometimes you want to ensure that the caller is an authenticated user, and not someone who bypassed the security of your machine with custom login information. You can achieve that through the following line of code:
MessageBox.Show(objPrincipal.Identity.IsAuthenticated.ToString())
It outputs in the MessageBox as either True or False depending on whether the user is authenticated or not. Another piece of information to ensure that your caller is not bypassing system security would be to check whether the account is operating as a guest. The following line of code accomplishes that:
MessageBox.Show(objIdentity.IsGuest.ToString())
IsGuest() returns either True or False, depending on whether the caller is authenticated as a guest. The final MessageBox in the example displays the ToString() value for the identity object. This is a value that tells you what type of identity it is, either a Windows identity or a non-Windows identity. The line of code that executes it is as follows:
MessageBox.Show(objIdentity.ToString())
The output from the IsString() method is shown in Figure 12-1.
Figure 12-1
Again, the principal and identity objects are used in verifying the identity or aspects of the identity of the caller attempting to execute your code. Based on this information, you can lock down or release certain system resources. You will learn how to lock down and release system resources through the code access permissions examples that follow.
Identity permissions are pieces of information, also called evidence, by which a piece of code can be identified. Examples of the evidence would be the strong name of the assembly or the digital signature associated with the assembly.
Tip | A strong name is a combination of the name of a program, its version number, and its associated crypto-graphic key and digital signature files. |
Identity permissions are granted by the runtime based on information received from the trusted host, or someone who has permission to provide the information. Therefore, they are permissions that you don’t specifically request. Identity permissions provide additional information to be used by the runtime when you configure items in the Caspol.exe utility. The additional information that the trusted host can supply includes the digital signature, the application directory, or the strong name of the assembly.