Adding Declarative Security Support
Although not strictly required, a custom permission should support declarative security so that developers can specify the custom permission when using declarative syntax for security actions such as requests, demands, or assertions. In fact, permission requests, link demands, and inheritance demands can only be made declaratively. For this reason, your custom code access permission cannot be requested or used with link demands or inheritance demands unless you provide support for declarative security. This topic describes how to implement an Attribute class that enables declarative security support for your custom permission.
Note
The attribute version of the custom permission must be defined in an assembly other than the assembly in which it is referenced. The custom permission should also be defined in that assembly. This is mandatory for declarative security, because the attribute is executed when the assembly is loaded, and the attribute may not have been created at the time the reference to it is encountered. Attempting to use a declarative permission in the same assembly in which it is defined results in a TypeLoadException being thrown.
Security attributes for declarations must derive (either directly or indirectly) from the SecurityAttribute class. If the permission is a code access permission, the attribute class derives from CodeAccessSecurityAttribute, which derives from SecurityAttribute. Security attribute classes must implement the CreatePermission method, which creates an instance of the permission object from the associated custom permission. Note that this associated custom permission class must be marked with the SerializableAttribute in order to be serialized into metadata by the compiler. For more information, see Implementing a Custom Permission.
The following code implements an attribute class for a Boolean permission named CustomPermission. In this example, the permission class has a single Boolean Unrestricted property that contains its state.
<AttributeUsageAttribute(AttributeTargets.All, AllowMultiple := True)> Public Class
CustomPermissionAttribute
Inherits CodeAccessSecurityAttribute
Private myUnrestricted As Boolean = False
Public Shadows Property Unrestricted() As Boolean
Get
Return myUnrestricted
End Get
Set
myUnrestricted = value
End Set
End Property
Public Sub New(action As SecurityAction)
MyBase.New(action)
End Sub
Public Overrides Function CreatePermission() As IPermission
If Unrestricted Then
Return New CustomPermission(PermissionState.Unrestricted)
Else
Return New CustomPermission(PermissionState.None)
End If
End Function
End Class
[AttributeUsageAttribute(AttributeTargets.All, AllowMultiple = true)]
public class CustomPermissionAttribute: CodeAccessSecurityAttribute
{
bool unrestricted = false;
public new bool Unrestricted
{
get{ return unrestricted; }
set{ unrestricted = value; }
}
public CustomPermissionAttribute(SecurityAction action): base (action)
{
}
public override IPermission CreatePermission()
{
if(Unrestricted)
{
return new CustomPermission(PermissionState.Unrestricted);
}
else
{
return new CustomPermission(PermissionState.None);
}
}
}
In this case, CreatePermission checks the internal Unrestricted property and creates the appropriate instance of a CustomPermission object. While only the Unrestricted property is used in this case, other custom permission attribute classes should support all possible states of the permission objects they support.
The use of CustomPermissionAttribute is illustrated in the following demand declaration:
<CustomPermissionAttribute(SecurityAction.Demand, Unrestricted := true)>
[CustomPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
See Also
Reference
Concepts
Creating Your Own Code Access Permissions
Implementing a Custom Permission