How to demand permissions by using Code Access Security (315529)



The information in this article applies to:

  • Microsoft Visual Studio .NET (2003), Professional Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Developer Edition
  • Microsoft Visual Studio .NET (2002), Professional Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Developer Edition

This article was previously published under Q315529

SUMMARY

Code Access Security (CAS) is an evidence-based security mechanism for .NET assemblies. You can use CAS to control the level of access that code has to protected resources and the operations that the code is permitted to perform. An assembly receives permissions at run time. The precise set of permissions is controlled by security policy and is determined by the evidence of the assembly that includes its strong name, the publisher, the zone where it originates, the location where it originates expressed as a URL, and a cryptographic hash of the assembly.

To reduce the chance that your code may be misused by other malicious code, you can demand that all callers are granted a specified permission. If any upstream caller in the current call stack does not have the demanded permission, a security exception is thrown.

All .NET Framework classes that perform restricted operations and access restricted resources such as the file system, demand permissions for you. As a result, when you use the .NET Framework classes you must not duplicate the permission demands. However, if you write code that accesses a resource without using the .NET Framework classes, you can demand permissions either programmatically or declaratively by using attributes.

You can also demand permissions programmatically or declaratively if you want to anticipate the security check. For example, you may have an application that executes a time-consuming calculation. After the calculation, the results are saved to a file. In this case, demand file access rights before you start the calculation. This makes sure that you have the correct permissions before you start the time-consuming calculation.
back to the top

MORE INFORMATION

Requirements

The following items describe the recommended hardware, software, network infrastructure, skills and knowledge, and service packs that you must have:
  • Visual Studio .NET 2002 or later

Prior Knowledge that is required:
  • Microsoft WinForm application development with Visual Studio .NET
  • Microsoft Visual C# fundamentals

back to the top

Demanding Permissions Programmatically

In this procedure you create a C# Windows application that is used to programmatically demand the permission to read and to write to the C:\Temp folder.
  1. Start Visual Studio .NET and then create a new Visual C# Windows application that is named CASTest.
  2. Drag a button control from the toolbox to the top of the form and then set the Name property to btnDemand and the Text property to Demand.
  3. Drag a label control from the toolbox, position the label control under the button, and then set the Name property to lblResult. Expand the label to the full width of the form and then increase the depth to contain several lines of text.
  4. Double-click Demand to add a click event procedure to the Form1.cs file. Page to the top of the file and then enter the following USING statements below the existing statements:
    using System.Text;
    using System.Security;
    using System.Security.Permissions;
    					
  5. Return to the Demand click event procedure at the bottom of the file and then add the following code to create a StringBuilder object that is used to create a result string and a FileIOPermission object that you use to demand the permission to access the C:\Temp folder:
    // Create a StringBuilder used to create the result string
    StringBuilder resultText = new StringBuilder();
    // Create an FileIOPermission for accessing the C:\Temp folder
    FileIOPermission permFileIO =
    new FileIOPermission(FileIOPermissionAccess.AllAccess, 
    "C:\\Temp");
    lblResult.Text = "";
    					
  6. Add the following code in a try block to demand the permission to access the C:\Temp folder by calling the Demand method of the FileIOPermission object. The code also appends a message that indicates success to the StringBuilder object.
    try 
    {
    // Demand the permission to access the C:\Temp folder.
    permFileIO.Demand();
    resultText.Append("The demand for permission to access the C:\\Temp folder succeeded.\n\n");
    }
    					
  7. Add the following catch block to process a SecurityException:
    catch (SecurityException se)
    {
    resultText.Append("The demand for permission to access the C:\\Temp folder failed.\nException message: ");
    resultText.Append(se.Message);
    resultText.Append("\n\n");
    }
    					
  8. After the catch block, add the following code to display the result text:
    lblResult.Text = resultText.ToString();
    					
  9. Build the project.
  10. On the Debug menu, click Start to run the application.
  11. Click Demand to demand the permission to access the C:\Temp folder.

    The demand is successful because the code that runs on your local computer receives the FullTrust permission set.
  12. Exit the application.

back to the top

Using Different Granted Permissions

You can use permission sets to organize permissions in convenient collections. For example, the Internet permission set contains permissions that are appropriate for assemblies that you download over the Internet. Code groups are used to associate permission sets with specific assemblies that are based on membership conditions. The membership conditions are evaluated by using specific aspects of the evidence of an assembly. For example, an assembly may belong to a particular code group if the originating location of that assembly is associated with a specific URL.

In this example, you configure security policy and then you create a new code group that is named InternetTestGroup. Members of this code group are assigned the built-in Internet permission set. Finally, you configure the code group to apply to any assembly with the originating location of C:\CASTestApplication.
  1. Click Control Panel and then double-click Administrative Tools.
  2. Double-click Microsoft .NET Framework Configuration.
  3. In the left pane, click Runtime Security Policy, click Machine, click Code Groups, and then click All_Code.

    You now see a list of built-in code groups.
  4. To create a new code group, click to select the All_Code node, right-click, and then click New....
  5. Type InternetTestGroup in the Name field. Type A test group to assign the Internet permission set to assemblies located in the C:\CASTestApplication folder in the Description field and then click Next.
  6. Now, you must specify a condition that determines the assemblies that are assigned the permission set that is associated with this code group. On the Choose the condition type for this code group drop-down list, click URL.
  7. Type the file name //c:/CASTestApplication/* in the URL field and then click Next.
  8. Now, you must specify the permission set that will be associated with the new code group.

    In the Use existing permission set drop-down list, click Internet, click Next, and then click Finish.
  9. Click to select the InternetTestGroup in the left pane, right-click, and then click Properties.
  10. Select This policy level will only have the permissions from the permission set associated with this code group check box, click Apply, and then click OK.

    This step prevents assemblies that are members of this code group from receiving additional permissions from other code groups.
  11. Run Microsoft Windows Explorer and then create the C:\CASTestApplication folder.
  12. Move to the bin\Debug folder that is located in your CASTest project folder and then copy the CASTest.exe assembly to the C:\CASTestApplication folder.
  13. Double-click CASTest.exe in the C:\CASTestApplication folder to start the application.
  14. Notice that a message appears and notifies you that the application is running in a partially-trusted context. This occurs because the Internet permission set is associated with the assembly.

    Dismiss the message.
  15. Click Demand.

    This time, the demand for the permission to access the C:\Temp folder is denied, and a security exception is thrown. This occurs because Internet applications are not permitted to access the local file system, other than through the use of Isolated storage.
  16. Exit the application.

back to the top

Demanding Permissions Declaratively

In addition to demanding permissions imperatively through code, you can also use attributes to demand permissions. Attributes can be associated with classes or with individual methods.

In this example, you use attributes to declaratively demand the permission to access the C:\Temp folder.
  1. Return to Visual Studio .NET.
  2. Add the following Helper method to the Form1 class:
    private void DemandFileIOPermission()
    {
    }
    					
  3. Add the following attribute immediately before the DemandFileIOPermission method:
    [FileIOPermissionAttribute(SecurityAction.Demand, Read = "C:\\TEMP")]
    					
  4. Add a new button to the form by dragging a button control from the toolbox to the form. Put the new button next to the first button, set the Name property to btnDeclarativeDemand, and then set the Text property to Declarative Demand.
  5. Double-click Declarative Demand to add a click event procedure to the Form1.cs file.
  6. Add the following code to the click event that you just created.

    This code is similar to the code in the Demand button. However, instead of calling explicitly the Demand method for a specified permission, you call the Helper function DemandFileIOPermission that has the FileIOPermission attribute.
    // Create a StringBuilder used to create the result string
    StringBuilder resultText = new StringBuilder();
    lblResult.Text = "";
    try 
    {
    // Call the helper function
    DemandFileIOPermission();
    resultText.Append("The declarative demand for permission to access the C:\\Temp folder succeeded.\n\n");
    }
    catch (SecurityException se)
    {
    resultText.Append("The declarative demand for permission to access the C:\\Temp folder failed.\nException message: ");
    resultText.Append(se.Message);
    resultText.Append("\n\n");
    }
    
    lblResult.Text = resultText.ToString();
    						
  7. Save and then rebuild the project.
  8. On the Debug menu, click Start to run the application.
  9. Click Declarative Demand.

    The result is a call to the DemandFileIOPermission private Helper method. The attributes that are associated with this method automatically result in a demand for permission to access the C:\Temp folder. By default, the demand is successful. Code that runs on your local computer receives the FullTrust permission set.
  10. Run Windows Explorer to move to the bin\Debug folder in your CASTest project folder and then copy the CASTest.exe assembly to the C:\CASTestApplication folder.
  11. Double-click CASTest.exe in the C:\CASTestApplication folder to run the application.
  12. Again, a message appears that notifies you that the application is running in a partially-trusted context. This occurs because the Internet permission set is associated with the assembly.

    Dismiss the message.
  13. Click Declarative Demand.

    The demand for the permission to access the C:\Temp folder is denied and a security exception is thrown. This occurs because Internet applications are not permitted to access the local file system, other than through the use of Isolated storage.

back to the top

REFERENCES

For more information about using Code Access Security, visit the following MSDN Web site: back to the top

Modification Type:MajorLast Reviewed:7/12/2005
Keywords:kbHOWTOmaster KB315529 kbAudDeveloper