programming4us
programming4us
SECURITY

Permissions: Extending the .NET Framework

9/14/2010 7:51:21 PM
CAS is fully extensible and allows you to create your own permission classes that integrate with the security framework to provide capabilities equivalent to the standard permission classes. The creation of custom permissions is relatively straightforward. The complexity of the identity, actions, or resources that your permission class represents defines how difficult the development task is. In the following sections, we demonstrate how to create and implement custom code-access permissions.

Creating Custom Code-Access Permissions

All code-access permissions must meet the following requirements:

  • Implement the IPermission interface

  • Implement the IStackWalk interface

  • Implement the ISecurityEncodable interface

  • Implement the IUnrestrictedPermission interface

  • Provide a constructor that takes a PermissionState argument

  • Be serializable

The simplest way to meet these requirements is to derive your permission class from the abstract CodeAccessPermission class, which we discussed in Section 2.1CodeAccessPermission declares implementation of the IPermission, IStackWalk, and ISecurityEncodeable interfaces, but only provides concrete implementations of the IStackWalk interface methods. Because the logic of the following methods depends on permission-specific state, you must provide implementations of them in your class: earlier in this chapter.

IPermission methods

  • Copy

  • Intersect

  • IsSubsetOf

  • Union

ISecurityEncodable methods

  • FromXml

  • ToXml

IUnrestrictedPermision method

  • IsUnrestrictedPermission

To meet the requirements of serialization, it is usually enough to apply the SerializableAttribute to your class definition. However, if your permission class requires nonstandard serialization processing because of the complex internal state it maintains, implement the ISerializable interface.

The CodeAccessPermission class defines an InheritenceDemand for the ControlEvidence and ControlPolicy elements of the SecurityPermissionCodeAccessPermission must have these permissions, or the runtime throws a SecurityException. class. The assembly containing your subclass of


To support declarative security syntax, create an attribute counterpart to your permission class. This involves creating a class that extends the System.Security.Permissions.CodeAccessSecurityAttribute class. Your class must:

  • Implement a single constructor that takes a SecurityAction argument

  • Override the CreatePermission method

  • Implement public properties that enable the configuration of the attribute's state

1. Designing the RadioPermission class

To demonstrate the creation and use of custom code-access permissions, imagine that we need to develop a managed library that allows an application to control a PC-based radio tuner. The radio tuner could be a hardware attachment to the PC or software that plays Internet-based radio stations; the implementation details are unimportant, but the library must allow code to:

  • Turn the radio on and off

  • Adjust the volume of the radio

  • Change the station the radio is tuned to

The goal is to create a custom code-access permission that you can use to control access to each of these actions. After all, you do not want to allow malicious code downloaded from competitive radio stations to casually change the tuning of the radio.

The best way to achieve fine-grained access control is to implement a code-access permission that represents a discrete set of actions; this is the same model used by the SecurityPermission class that we described in Section 2.2 earlier in this chapter. Because the number of possible actions is small and well-defined, this model fits your needs well. Another common approach is to implement a permission hierarchy, where permission to perform a highly trusted action gives permission to perform all lesser-trusted actions; however, the actions you need to represent in this case do not fit this model well.

To give the programmers using the custom permission flexibility, you want to provide both imperative and declarative syntax support. This will also allow application developers to build permission requests for your permission into their assemblies. Create two classes and one enumeration:


RadioPermission

The custom code-access permission that controls access to the managed library for the radio tuner


RadioPermissionAttribute

The attribute counterpart to RadioPermission that provides declarative syntax support


RadioAction

An enumeration that defines values that represent each of the controlled actions

For convenience, we include all three types in a single source file named Radio.cs (C#) and Radio.vb (Visual Basic .NET). We will build this into a library named Radio.dll, which programmers will use in the development of the managed radio tuner library, the configuration of .NET security policy, and to make permission requests in assemblies that access the managed library. Although the code is straightforward, it is lengthy, so we break the listings into manageable sections for explanation.

2. Defining imports and assembly scope attributes

Aside from importing the necessary namespace references, the first thing to do is to specify the assembly scope attributes AssemblyKeyFile and AssemblyVersion to give Radio.dll a strong name. Because Radio.dll contains security classes used to extend CAS, you must configure it as a fully trusted assembly in the runtime's security policy. For this example, the AssemblyKeyFile attribute references a key file named Keys.snk, which you can generate later using the .NET Strong Name tool (Sn.exe):

# C#

using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;

[assembly:AssemblyKeyFile("Keys.snk")]
[assembly:AssemblyVersion("1.0.0.0")]

namespace OReilly.ProgrammingDotNetSecurity {

# Visual Basic .NET

Imports System
Imports System.Reflection
Imports System.Security
Imports System.Security.Permissions

<assembly:AssemblyKeyFile("Keys.snk")>
<assembly:AssemblyVersion("1.0.0.0")>

Namespace OReilly.ProgrammingDotNetSecurity

3. Defining the RadioAction enumeration

RadioPermission represents control of a discrete set of actions. The RadioAction enumeration represents each of the actions to which RadioPermission controls access. RadioAction also includes a value to represent no permission and a value to represent full or unrestricted permission.

To simplify the implementation of your permission model, apply the Flags attribute to the RadioAction enumeration. The Flags attribute allows you to use the values of the RadioAction enumeration as bit fields, enabling you to manipulate and compare RadioAction values with bitwise operators. Table 1 lists the members of RadioAction and shows their binary and hex values. From the binary values, it is easy to see how RadioAction identifies the individual actions to which a RadioPermission object represents access.

Table 1. Values of the RadioAction enumeration
Value Binary value Hex value Description
None 000 0 No access to perform any actions with the radio
StartStop 001 1 Permission to turn the radio on and off
Channel 010 2 Permission to change the radio's channel
Volume 100 4 Permission to change the radio's volume
All 111 7 Permission to perform any of the above actions

Finally, because you use RadioAction values inside SecurityPermission objects (which must be serializable), you also mark RadioAction as Serializable:

# C#

// Define enumeration to represent the set of possible permissions.
[Flags, Serializable]
public enum RadioAction {
None = 0x00, // No permissions
StartStop = 0x01, // Permission to start and stop the radio
Channel = 0x02, // Permission to change the channel
Volume = 0x04, // Permission to change the volume
All = 0x07 // All permissions
}

# Visual Basic .NET

' Define enumeration to represent the set of possible permissions.
<Flags, Serializable> _
Public Enum RadioAction
None = &H00 ' No permissions
StartStop = &H01 ' Permission to start and stop the radio
Channel = &H02 ' Permission to change the channel
Volume = &H04 ' Permission to change the volume
All = &H07 ' All permissions
End Enum

4. Defining the RadioPermission class

The class declaration for RadioPermission specifies that it is sealed (C#) and NotInheritable (Visual Basic .NET). There is no need to allow anybody to extend the RadioPermission class, and it stops malicious code from subclassing RadioPermission in an attempt to subvert security restrictions.

RadioPermission extends CodeAccessPermission, implements the IUnrestricted interface, and is Serializable. The CodeAccessPermission base class already implements the functionality defined in the IStackWalk interface so you do not have to implement the Assert, Demand, Deny, and PermitOnly methods; this simplifies the development of custom code-access permissions. However, you still need to implement the permission-specific Copy, Intersect, IsSubsetOf, and Union methods defined in IPermission, and the FromXml and ToXml methods defined in ISecurityEncodable, all of which CodeAccessPermission declares as abstract.

Declare a single private data member named RadioActions of type RadioAction. This holds a bit field representing the actions to which a specific RadioPermissionActions property to provide controlled access to the private RadioActions member: object grants access. Implement the

# C#

// Define the RadioPermission class.
[Serializable]
public sealed class RadioPermission :
CodeAccessPermission, IUnrestrictedPermission {

// Private member to signal permitted actions.
private RadioAction RadioActions;

// Property to provide access to the enabled radio actions.
public RadioAction Actions {

get {
return RadioActions;
}
set {
if ((value & (~RadioAction.All)) != 0) {
throw new
ArgumentException("Inavalid RadioAction value");
} else {
RadioActions = value;
}
}
}

# Visual Basic .NET

' Define the RadioPermission class.
<Serializable> _
Public NotInheritable Class RadioPermission
Inherits CodeAccessPermission

' Private member to signal permitted actions.
Private RadioActions As RadioAction

' Property to provide access to the enabled radio actions.
Public Property Actions( ) As RadioAction
Get
Return RadioActions
End Get
Set (ByVal Value As RadioAction)
If (value And (Not RadioAction.All)) <> 0 Then
Throw New ArgumentException _
("Inavalid RadioAction value")
Else
RadioActions = value
End If
End Set
End Property


Declare two constructors for RadioPermission. All code-access permission classes that extend CodeAccessPermission must implement a constructor that takes a PermissionState argument. Passing the constructor the value PermissionState.None creates a RadioPermission that represents no permissions by setting RadioActionsRadioAction.None, whereas passing the PermissionState.Unrestricted value creates a RadioPermission object representing full permission by setting RadioActionsRadioAction.All. to to

Because you use a bit field to represent each permitted action, it is easy to represent an unrestricted permission simply by switching on all action bits (RadioAction.All equals 111 in binary). In other permission models, you may need to implement a separate Boolean data member to represent an unrestricted state.

The second constructor takes a member of the RadioAction enumeration, confirms that it is valid, and sets the private RadioActions member to the value of the argument:

# C#

// Constructor that takes a PermissionState.
public RadioPermission (PermissionState state) {

if (state == PermissionState.None) {
this.RadioActions = RadioAction.None;
} else if (state == PermissionState.Unrestricted) {
this.RadioActions = RadioAction.All;
} else {
throw new ArgumentException("state");
}
}

// Constructor that takes a RadioAction specifying the set
// of actions permitted by this RadioPermission object.
public RadioPermission (RadioAction actions) {

// Ensure we have a valid actions value.
if ((actions & (~RadioAction.All)) != 0) {
throw new ArgumentException("Inavalid RadioAction value");
} else {
RadioActions = actions;
}
this.RadioActions = actions;
}


# Visual Basic .NET

' Constructor that takes a PermissionState.
Public Sub New(ByVal state As PermissionState)

If state = PermissionState.None Then
Me.RadioActions = RadioAction.None
Else If state = PermissionState.Unrestricted Then
Me.RadioActions = RadioAction.All
Else
Throw New ArgumentException("state")
End If
End Sub

' Constructor that takes a RadioAction specifying the set
' of actions permitted by this RadioPermission object.
Public Sub New(ByVal actions As RadioAction)

' Ensure we have a valid actions value.
If (actions And (Not RadioAction.All)) <> 0 Then
Throw New ArgumentException("Inavalid RadioAction value")
Else
RadioActions = actions
End If
Me.RadioActions = actions
End Sub


5. Implementing the IUnrestrictedPermission interface

The IUnrestrictedPermission interface defines the IsUnrestricted method, which returns a Boolean indicating whether a permission object represents an unrestricted state. In the case of RadioPermission, you can easily calculate the response by comparing the value of the private RadioActions member with the value RadioAction.All and returning the result:

# C#

// Return whether permission represents unrestricted access.
public bool IsUnrestricted( )
{
return RadioActions == RadioAction.All;
}


# Visual Basic .NET

' Return whether permission represents unrestricted access.
Public Function IsUnrestricted( ) As Boolean
Return RadioActions = RadioAction.All
End Function

6. Implementing the IPermission interface

Both the IStackWalk and IPermission interfaces define a method named Demand. The CodeAccessPermission base class implements all members of the IStackWalkDemand method from the IPermission interface, leaving you with the Copy, Intersect, Union, and IsSubsetOf interface, and you do not need to implement the methods to implement.

The Copy method returns a clone of the permission object. In the case of RadioPermission, this is a simple matter of calling one of the constructors and passing the current RadioActions value. If your permission class uses objects to represent state, Copy must perform a deep copy and create copies of all contained objects:

# C#

// Create a copy the RadioPermission.
public override IPermission Copy( ) {

return new RadioPermission(RadioActions);
}

# Visual Basic .NET

' Create a copy the RadioPermission.
Public Overrides Function Copy( ) As IPermission

Return New RadioPermission(RadioActions)
End Function

The Intersect method returns a new IPermission that represents the logical intersection of the current RadioPermission and another. Because RadioPermissionRadioPermission objects is the set of actions permitted by both objects. For example, if the current RadioPermission grants Volume and Channel control and the other grants only Volume control, the intersection of the two is a RadioPermissionVolume control. Because the Flags attribute allows you to treat values of the RadioAction enumeration as bit fields, you can express the intersection logic using a bitwise And on the RadioActions members of the two original RadioPermission objects. represents permission to perform a discrete set of actions, the intersection of two that grants only

# C#

// Return an intersection of this and another RadioPermission
// object.
public override IPermission Intersect(IPermission target) {

// Return null if the target argument is null.
if (target == null) {
return null;
}

// Ensure the target argument is another RadioPermission
// object, if not throw an ArgumentException.
if (target is RadioPermission) {

RadioPermission r = (RadioPermission)target;

// Calculate the intersection of the radio actions
// from this and the target RadioPermission.
RadioAction i =
this.RadioActions & r.RadioActions;

// Return a new RadioPermission.
return new RadioPermission(i);

} else {
throw new ArgumentException("target");
}
}


# Visual Basic .NET

' Return an intersection of this and another RadioPermission
' object.
Public Overrides Function Intersect(ByVal target As IPermission) _
As IPermission

' Return null if the target argument is null.
If target Is Nothing Then
Return Nothing
End If

' Ensure the target argument is another RadioPermission
' object, if not throw an ArgumentException.
If TypeOf target Is RadioPermission Then

Dim r As RadioPermission = _
CType(target, RadioPermission)

' Calculate the intersection of the radio actions
' from this and the target RadioPermission.
Dim i As RadioAction = Me.RadioActions And _
r.RadioActions

' Return a new RadioPermission.
Return New RadioPermission(i)

Else
Throw New ArgumentException("target")
End If
End Function


The Union method returns a new IPermission that represents the logical union of the current RadioPermission and another. For example, if one RadioPermissionChannel control and the other grants Volume control, the union of the two is a RadioPermission that grants both Volume and Channel control. The implementation of the Union method is similar to the Intersect method, but uses a bitwise Or operator on the RadioActions members of the two original RadioPermission objects to calculate the union: grants

# C#

// Return the union of this and another RadioPermission object.
public override IPermission Union(IPermission other) {

// Return null if the other argument is null.
if (other == null) {
return null;
}

// Ensure the other argument is another RadioPermission object
// if not throw an ArgumentException.
if (other is RadioPermission) {

RadioPermission r = (RadioPermission)other;

// Calculate the union of the radio actions
// from this and the other RadioPermission.
RadioAction u =
this.RadioActions | r.RadioActions;

// Return a new RadioPermission
return new RadioPermission(u);
} else {
throw new ArgumentException("other");
}
}


# Visual Basic .NET

' Return the union of this and another RadioPermission object.
Public Overrides Function Union(ByVal other As IPermission) _
As IPermission

' Return null if the other argument is null.
If other Is Nothing Then
Return Nothing
End If

' Ensure the other argument is another RadioPermission object
' if not throw an ArgumentException.
If TypeOf other Is RadioPermission Then

Dim r As RadioPermission = CType(other, RadioPermission)

' Calculate the union of the radio actions
' from this and the other RadioPermission.
Dim u As RadioAction = Me.RadioActions _
Or r.RadioActions

' Return a new RadioPermission
Return New RadioPermission(u)

Else
Throw New ArgumentException("other")
End If
End Function


The IsSubsetOf method returns a Boolean value indicating whether the current RadioPermission is a subset of the RadioPermission passed as an argument to the method. For example, if the current RadioPermission allowed Volume control, and the one specified by the argument allowed both Volume and Channel control, then the current RadioPermission is a subset of the other. As with the Intersect and Union methods, we perform the subset relationship test using bitwise operators.

# C#

// Determines if this RadioPermission is a subset of the provided
// RadioPermission.
public override bool IsSubsetOf(IPermission target) {

// Return false if the target argument is null.
if (target == null) {

return false;
}

// Ensure the target argument is another RadioPermission
// object, if not throw an ArgumentException.
if (target is RadioPermission) {

RadioPermission r = (RadioPermission)target;

// Determine if the provided set of actions are
// a subset of the current permissions actions.
return (this.RadioActions
& (~r.RadioActions)) == 0;

} else {

throw new ArgumentException("target");
}
}


# Visual Basic .NET

' Determines if this RadioPermission is a subset of the provided
' RadioPermission.
Public Overrides Function IsSubsetOf _
(ByVal target As IPermission) As Boolean

' Return false if the target argument is null.
If target Is Nothing Then

Return False
End If

' Ensure the target argument is another RadioPermission
' object, if not throw an ArgumentException.
If TypeOf target Is RadioPermission Then

Dim r As RadioPermission = _
CType(target, RadioPermission)

' Determine if the provided set of actions are
' a subset of the current permissions actions.
Return (Me.RadioActions And _
(Not r.RadioActions)) = 0
Else
Throw New ArgumentException("target")
End If
End Function

7. Implementing the ISecurityEncodable interface

The ToXml method returns a SecurityElement. The SecurityElement contains a simple XML object model representing the state of the RadioPermission object. The runtime uses the ToString method of SecurityElement to render permission objects to XML for writing to the security policy files. The XML representation is also useful when debugging CAS programming issues.

The XML representation of all code-access permissions must have a root element named "IPermission." The internal structure of this element is up to you, as long as the FromXml method (discussed next) can accurately recreate the state of a permission object from the XML. Here is an example of the XML used to represent a RadioPermission object that represents access to the StartStop action only.

<IPermission class="OReilly.ProgrammingDotNetSecurity.RadioPermission, 
Radio, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc5e18bc387194b3"
version="1"
StartStop="true"/>

The XML structure you have implemented for RadioPermission is consistent with that used by the standard permission classes. Use attributes, as opposed to child elements, to store state data, and include active state only, assuming missing values have their default values. If the RadioPermission object represents access to all actions, include a single Unrestricted = true attribute instead of including values for each of the individual actions. The version attribute identifies the XML format to provide backward compatibility in case future versions of the RadioPermission use different XML representations:

# C#

// Convert the Radio Permission to a SecurityElement.
public override SecurityElement ToXml( ) {

// Create a new "IPermission" element.
SecurityElement se = new SecurityElement("IPermission");

// Add fully qualified type name for the RadioPermission.
se.AddAttribute("class",this.GetType( ).AssemblyQualifiedName);

// Add version of "1" to be consistent with other permission
// classes
se.AddAttribute("version", "1");

// Add the radio action state, only write out active
// permissions.
if (this.IsUnrestricted( )) {

// Write only the unrestricted attribute if the
// permission is unrestricted.
se.AddAttribute("Unrestricted", "true");
} else {

// Write out the individual actions that are granted.
if ((RadioActions & RadioAction.StartStop) != 0) {
se.AddAttribute("StartStop", "true");
}
if ((RadioActions & RadioAction.Channel) != 0) {
se.AddAttribute("Channel", "true");
}
if ((RadioActions & RadioAction.Volume) != 0) {
se.AddAttribute("Volume", "true");
}
}

// Return the new SecurityElement.
return se;
}

# Visual Basic .NET

' Convert the Radio Permission to a SecurityElement.
Public Overrides Function ToXml( ) As SecurityElement

' Create a new "IPermission" element.
Dim se As SecurityElement = New SecurityElement("IPermission")

' Add fully qualified type name for the RadioPermission.
se.AddAttribute("class",Me.GetType( ).AssemblyQualifiedName)

' Add version of "1" to be consistent with other permission
' classes
se.AddAttribute("version", "1")

' Add the radio action state, only write out active
' permissions.
If Me.IsUnrestricted( ) Then

' Write only the unrestricted attribute if the
' permission is unrestricted.
se.AddAttribute("Unrestricted", "true")
Else

' Write out the individual actions that are granted.
If (RadioActions And RadioAction.StartStop) <> 0 Then
se.AddAttribute("StartStop", "true")
End If
If (RadioActions And RadioAction.Channel) <> 0 Then
se.AddAttribute("Channel", "true")
End If
If (RadioActions And RadioAction.Volume) <> 0 Then
se.AddAttribute("Volume", "true")
End If
End If

' Return the new SecurityElement.
Return se
End Function

The FromXml method recreates the state of a RadioPermission object that was rendered previously to XML using the ToXml method. Check first to see if the XML represents an unrestricted permission; if it does not, look for each individual action:
# C#

// Extract state from a SecurityElement.
public override void FromXml(SecurityElement e) {

// Ensure we have a SecurityElement to work with
if (e == null) throw new ArgumentNullException("e");

// Ensure the SecurityElement is an IPermission
if (e.Tag != "IPermission") {throw new ArgumentException(
"Element must be IPermission");
} else {

// Determine if the permission is unrestricted
if (e.Attribute("Unrestricted") == "true") {

RadioActions = RadioAction.All;
} else {

// Look for each individual action attribute to
// build the set of permissions
RadioActions = RadioAction.None;

if (e.Attribute("StartStop") == "true") {
RadioActions =
RadioActions | RadioAction.StartStop;
}
if (e.Attribute("Channel") == "true") {
RadioActions =
RadioActions | RadioAction.Channel;
}
if (e.Attribute("Volume") == "true") {
RadioActions =
RadioActions | RadioAction.Volume;
}
}
}
}
}


# Visual Basic .NET

' Extract state from a SecurityElement.
Public Overrides Sub FromXml(ByVal e As SecurityElement)

' Ensure we have a SecurityElement to work with
If e Is Nothing Then
Throw New ArgumentNullException("e")
End If

' Ensure the SecurityElement is an IPermission
If e.Tag <> "IPermission" Then
Throw New ArgumentException("Element must be IPermission")
Else

' Determine if the permission is unrestricted
If e.Attribute("Unrestricted") = "true" Then
RadioActions = RadioAction.All
Else
' Look for each individual action attribute to
' build the set of permissions
RadioActions = RadioAction.None

If e.Attribute("StartStop") = "true" Then
RadioActions = _
RadioActions Or RadioAction.StartStop
End If
If e.Attribute("Channel") = "true" Then
RadioActions = _
RadioActions Or RadioAction.Channel
End If
If e.Attribute("Volume") = "true" Then
RadioActions = _
RadioActions Or RadioAction.Volume
End If
End If
End If
End Sub
End Class

8. Defining the RadioPermissionAttribute class

We begin the declaration of the RadioPermissionAttribute class by using the AttributeUsage attribute to define the program elements you can apply the RadioPermissionAttribute to.

RadioPermissionAttribute extends the CodeAccessSecurityAttibute class, which provides the base class from which all permission attributes must extend. Implement a single constructor that all permission attributes extending CodeAccessSecurityAttibute must define. The constructor takes a value from the SecurityActionSection 1.2 for details: enumeration, which describes the CAS operation invoked by a declarative security statement; see

# C#

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor
| AttributeTargets.Class | AttributeTargets.Struct
| AttributeTargets.Assembly, AllowMultiple = true,
Inherited = false )]
[Serializable]
public sealed class RadioPermissionAttribute :
CodeAccessSecurityAttribute {

// Constructor to take SecurityAction, simply calls base
// class constructor.
public RadioPermissionAttribute(SecurityAction action):
base( action ) {}

# Visual Basic .NET

<AttributeUsage(AttributeTargets.Method Or _
AttributeTargets.Constructor Or AttributeTargets.Class Or _
AttributeTargets.Struct Or AttributeTargets.Assembly, _
AllowMultiple := True, Inherited := False), Serializable> _
Public NotInheritable Class RadioPermissionAttribute
Inherits CodeAccessSecurityAttribute

' Constructor to take SecurityAction, simply calls base
' class constructor.
Public Sub New(ByVal action As SecurityAction)
MyBase.New(action)
End Sub

As with RadioPermission, the RadioPermissionAttribute class contains a private data member named RadioActions (of type RadioAction) to identify which actions the RadioPermissionAttribute object represents. Four properties provide controlled access to configure the value of the private RadioActions member. The first property, named Actions, allows you to provide a RadioAction value to configure the state of all actions in a single call. The other three attributes, named StartStop, Channel, and Volume, allow you to configure the individual bits of RadioActions to set whether an individual action is permitted or not:
# C#

// Private member to signal permitted actions.
private RadioAction RadioActions = RadioAction.None;

// Property allows all actions to be configured in one call
// using values from the RadioAction enumeration
public RadioAction Actions {
get { return RadioActions; }
set { RadioActions = value; }
}

// Property to allow StartStop permission to be switched on
// and off
public bool StartStop {
get { return (RadioActions & RadioAction.StartStop) != 0; }
set {
if (value) {
RadioActions = RadioActions | RadioAction.StartStop;
} else {
RadioActions = RadioActions & ~RadioAction.StartStop;
}
}
}

// Property to allow Channel permission to be switched on
// and off
public bool Channel {
get { return (RadioActions & RadioAction.Channel) != 0; }
set {
if (value) {
RadioActions = RadioActions | RadioAction.Channel;
} else {
RadioActions = RadioActions & ~RadioAction.Channel;
}
}
}

// Property to allow Volume permission to be switched on
// and off
public bool Volume {
get { return (RadioActions & RadioAction.Volume) != 0; }
set {
if (value) {
RadioActions = RadioActions | RadioAction.Volume;
} else {
RadioActions = RadioActions & ~RadioAction.Volume;
}
}
}


# Visual Basic .NET

' Private member to signal permitted actions.
Private RadioActions As RadioAction = RadioAction.None

' Property allows all actions to be configured in one call
' using values from the RadioAction enumeration
Public Property Actions( ) As RadioAction
Get
Return RadioActions
End Get
Set (ByVal Value As RadioAction)
RadioActions = value
End Set
End Property

' Property to allow StartStop permission to be switched on
' and off
Public Property StartStop( ) As Boolean
Get
Return (RadioActions And RadioAction.StartStop) <> 0
End Get
Set (ByVal Value As Boolean)
If value Then
RadioActions = RadioActions Or RadioAction.StartStop
Else
RadioActions = RadioActions And _
(Not RadioAction.StartStop)
End If
End Set
End Property

' Property to allow Channel permission to be switched on
' and off
Public Property Channel( ) As Boolean
Get
Return (RadioActions And RadioAction.Channel) <> 0
End Get
Set (ByVal Value As Boolean)
If value Then
RadioActions = RadioActions Or RadioAction.Channel
Else
RadioActions = RadioActions And _
(Not RadioAction.Channel)
End If
End Set
End Property

' Property to allow Volume permission to be switched on
' and off
Public Property Volume( ) As Boolean
Get
Return (RadioActions And RadioAction.Volume) <> 0
End Get
Set (ByVal Value As Boolean)
If value Then
RadioActions = RadioActions Or RadioAction.Volume
Else
RadioActions = RadioActions And _
(Not RadioAction.Volume)
End IF
End Set
End Property


Despite its simplicity, the CreatePermission method is the most important method of a permission attribute. It allows the runtime to create permission objects from the declarative security statements contained in your code. The CreatePermission method returns a newly created RadioPermission using the value of attributes RadioActions member:

# C#

// Creates and returns an RadioPermission object
// based on the configured radio actions.
public override IPermission CreatePermission( ) {

return new RadioPermission(RadioActions);
}
}
}

# Visual Basic .NET

' Creates and returns an RadioPermission object
' based on the configured radio actions.
Public Overrides Function CreatePermission( ) As IPermission
Return New RadioPermission(RadioActions)
End Function
End Class
End Namespace

9. Building the Radio.dll library

The RadioAction, RadioPermission, and RadioPermissionAttribute classes are all contained in a single source file named Radio.cs (C#) or Radio.vb (Visual Basic .NET). Before you can build the Radio.dll library containing the new security classes, you must create a key file named Keys.snk to satisfy the reference contained in the AssemblyKeyFile attribute. Create the Keys.snk file and compile the Radio.dll library using the following commands:

# C# 

sn -k Keys.snk
csc /target:library Radio.cs

# Visual Basic .NET

sn -k Keys.snk
vbc /target:library Radio.vb

10. Using RadioPermission to enforce security

RadioPermission is now ready to protect the methods in the managed library that provides access to the radio tuner. As demonstrated in the following code fragments, you can use RadioPermission in exactly the same ways as the standard permission classes:

# C#

// An imperative assert of RadioPermission granting Volume control
RadioPermission r = new RadioPermission(RadioAction.Volume);
r.Assert( );

// A declarative demand for permission to change the radio channel
[RadioPermission(SecurityAction.Demand, Channel = true)]

// A minimum permission request for unrestricted access to the radio
[assembly:RadioPermission(SecurityAction.RequestMinimum,
Unrestricted = true)]

# Visual Basic .NET

' An imperative assert of RadioPermission granting Volume control
Dim r As RadioPermission = New RadioPermission(RadioAction.Volume)
r.Assert( )

' A declarative demand for permission to change the radio channel
<RadioPermission(SecurityAction.Demand, Channel := True)> _

' A minimum permission request for unrestricted access to the radio
<assembly:RadioPermission(SecurityAction.RequestMinimum, _
Unrestricted := True)>

Once you have developed the secure class library that enables managed code to control the PC radio tuner, you must configure the security policy to grant access to the appropriate code. First, you must understand how security policy calculates the set of permissions to grant to an assembly. Then you need to understand how to use the security administration tools supplied with the .NET Framework to configure security policy.

Other  
 
 
Video tutorials
- How To Install Windows 8

- How To Install Windows Server 2012

- How To Install Windows Server 2012 On VirtualBox

- How To Disable Windows 8 Metro UI

- How To Install Windows Store Apps From Windows 8 Classic Desktop

- How To Disable Windows Update in Windows 8

- How To Disable Windows 8 Metro UI

- How To Add Widgets To Windows 8 Lock Screen

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010
programming4us programming4us
programming4us
 
 
programming4us