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.
Stack Walks
Demands enforce security by performing an analysis (called a stack walk) in which every calling function (or stack frame) in the current call stack is examined for the specified permission. When a demand is triggered the following occurs.
The stack walk begins at the callers stack frame not the current stack where the demand occurs. For example, if Method A calls Method B and method B has a demand, the stack walk begins at method A's stack frame. Method B is never evaluated as part of the stack walk.
The stack walk proceeds through the call stack until it reaches the program entry point of the stack (usually the Main method) or until a stack walk modifier like an assert is found. For information on stack walk modifiers see, Overriding Security Checks.
When a demand and a stack walk modifier (an assert, for example) for the same permission appear on the same stack frame, the demand takes precedence.
Declarative and imperative syntax exhibit no difference in behavior.
Note that a demand placed on your program entry point never gets evaluated because the stack walks always begins at calling stack frame, but in this case, there is no such calling frame to evaluate. Therefore demands placed on a program entry point always succeed.
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
[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
public static void ReadData()
{
CustomPermission MyPermission = new CustomPermission(PermissionState.Unrestricted);
MyPermission.Demand();
//Read from a custom resource.
}
Note |
---|
The optimization behavior for the demand operation differs between 64 bit and 32 bit platforms. On 64 bit platforms, a demand will not check the grant set of the assembly containing the demand in cases where no other calling assemblies are present. However, this optimization does not cause an elevation of privilege because a stack walk is still performed when calling assemblies are present. On 32 bit platforms the demand operation checks the grant set of the assembly containing the demand and all calling assemblies. |
See Also
Reference
Concepts
Security Demands
Creating Your Own Code Access Permissions
Adding Declarative Security Support
Writing Secure Class Libraries