Demands

You can use the security demand call declaratively or imperatively to specify the permissions that direct or indirect callers must have to access your library. Direct callers explicitly call static or instance methods of your library, while indirect callers call static or instance methods of another library that calls your library. When you use a demand, any application that includes your code will execute only if all direct and indirect callers have the permissions that the demand specifies. Demands are particularly useful in situations in which your class library uses protected resources that you do not want to be accessed by untrusted code. Demands can be placed in code using either imperative or declarative syntax.

Note that most classes in the .NET Framework already have demands associated with them, so you do not need to make an additional demand whenever you use a class that accesses a protected resource. For example, the StreamWriter class automatically makes a security demand for FileIOPermission whenever it is opened. If you make a demand for FileIOPermission when you use the StreamWriter class, you will cause a redundant and inefficient stack walk to occur. You should use demands to protect custom resources that require custom permissions.

Demands can be either declarative or imperative.

Declarative Demands

Declarative demands place information into your code's metadata using attributes. You can use declarative syntax to place a demand at either the class or the method level of your code.

If you place a declarative security check at the class level, it applies to each class member. However, if you place a declarative security check at the member level, it applies to only that member and overrides the permission specified at the class level, if one exists. For example, suppose you specify at the class level that PermissionA is required, and for that class's Method1 you indicate that PermissionB is required. When Method1 is called, a security check will look only for PermissionB, but other methods of the class will still require PermissionA.

The following example places a declarative demand for a custom permission called CustomPermission on all callers of the ReadData method. This permission is a hypothetical custom permission and does not exist in the .NET Framework. The custom permission has a separately defined CustomPermissionAttribute that makes the demand. In this case, it takes a SecurityAction.Demand flag in order to specify the type of demand the attribute will perform.

<CustomPermissionAttribute(SecurityAction.Demand, Unrestricted := True)>Public Shared Function  ReadData() As String
   'Read from a custom resource.
End Function
[C#]
[CustomPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
public static string ReadData()
{
   //Read from a custom resource.
}

Imperative Demands

Imperative demands are placed at the method level of your code by creating a new instance of a permission object and calling that object's Demand method. Imperative syntax cannot be used to place demands at the class level.

The imperative demand that you place in your code effectively helps protect all the remaining code in the method in which the Demand method is called. The security check is performed when the Demand is executed; if the security check fails, a SecurityException is thrown and the rest of the code in that method or member is never executed unless the SecurityException is caught and handled.

The following example uses imperative syntax to place a demand on all callers for the custom permission CustomPermission. This code creates a new instance of the CustomPermission class, passing the PermissionState.Unrestricted flag to the constructor. The Demand method is then called.

Public Shared Sub ReadData()
   Dim MyPermission As New CustomPermission(PermissionState.Unrestricted)
   MyPermission.Demand()
   'Read from a custom resource.
End Sub  
[C#]
public static void ReadData()
{
   CustomPermission MyPermission = new CustomPermission(PermissionState.Unrestricted);
   MyPermission.Demand();

   //Read from a custom resource.
}

See Also

Extending Metadata Using Attributes | Security Demands | Code Access Security | Creating Your Own Code Access Permissions | Adding Declarative Security Support | Writing Secure Class Libraries | SecurityException Class