Comparing Declarative and Imperative Security

Now that you understand how security policy is managed, even if you aren't the person doing the managing, it is important to understand how we make use of code access security in our code. Much of the CLR already interacts with security policy using declarative and imperative security requests. These requests are made in the form of attributes and code that instantiates a specific security- related class. When security requests are made in the form of attributes, this is referred to as declarative security . When security requests are made in the form of lines of code within a method body, this is referred to as imperative security . The results are roughly the same regardless of the method used.

NOTE

Some security requests can be made only declaratively , that is, as attributes.

Listing 18.1 provides two examples. One demonstrates declarative security and the other precisely the same request using an imperative syntax. Note that while the code in Listing 18.1 demonstrates both declarative and imperative syntax, the PrincipalPermissionAttribute and the PrincipalPermission class are considered part of role-based security rather than code access security. (I chose this example to demonstrate syntax and introduce other forms of security in .NET.)

Listing 18.1 Using Declarative and Imperative Role-Based Permissions Checks
 1:  Imports System.Security.Permissions 2:  Imports System.Threading 3:  Imports System.Security.Principal 4: 5:  Public Class Form1 6:      Inherits System.Windows.Forms.Form 7: 8:  [ Windows Form Designer generated code ] 9:    Private Const user As String = "  domain\user  " 10:   Private Const role As String = Nothing 11: 12:   Private Sub Button1_Click(ByVal sender As System.Object, _ 13:     ByVal e As System.EventArgs) Handles Button1.Click 14: 15:     Const mask As String = _ 16:       "Current principal is: {0}" 17: 18:     Debug.WriteLine(String.Format(mask, _ 19:       Thread.CurrentThread.CurrentPrincipal.Identity.Name)) 20: 21:     DeclarativePermissionRequired() 22: 23:   End Sub 24: 25:   Private Sub Button2_Click(ByVal sender As System.Object, _ 26:     ByVal e As System.EventArgs) Handles Button2.Click 27: 28:     Const mask As String = _ 29:       "Current principal is: {0}" 30: 31:     Debug.WriteLine(String.Format(mask, _ 32:       Thread.CurrentThread.CurrentPrincipal.Identity.Name)) 33: 34:     ImperativePermissionRequired() 35: 36:   End Sub 37: 38:   <PrincipalPermission(SecurityAction.Demand, _ 39:     Name:=user, role:=role)> _ 40:   Public Sub DeclarativePermissionRequired() 41: 42:     MessageBox.Show("You have permission!") 43: 44:   End Sub 45: 46:   Public Sub ImperativePermissionRequired() 47: 48:     Dim Permission As _ 49:       System.Security.Permissions. _ 50:         PrincipalPermission = _ 51:       New System.Security.Permissions. _ 52:         PrincipalPermission(user, role) 53: 54:     Permission.Demand() 55: 56:     MessageBox.Show("You have permission!") 57:   End Sub 58: 59:   Private Sub Form1_Load(ByVal sender As System.Object, _ 60:     ByVal e As System.EventArgs) Handles MyBase.Load 61: 62:     Thread.CurrentThread.CurrentPrincipal = _ 63:       New WindowsPrincipal(WindowsIdentity.GetCurrent) 64: 65:   End Sub 66: End Class 

The WindowsPrincipal class used in line 63 implements the IPrincipal interface. A principal object represents the user identity and roles under which the code is running. (This is part of roles-based security in .NET, but the example also demonstrates the declarative and imperative syntax.) The Form.Load event establishes the current Windows user as the current principal. This means that the code is running on behalf of the current user.

TIP

You can use the .NET utility permview .exe ”as in permview.exe myassembly.dll ”to view the declarative permissions used by an assembly.

Lines 12 through 23 write the identity of the current principal and call DeclarativePermissionRequired . The subroutine DeclarativePermissionRequired uses the PrincipalPermissionAttribute ”a declarative demand ”to demand that the identity of the person running this method must be the name of the supplied user and be in the role defined by the argument role . Because role is initialized to Nothing in line 10 we are only verifying that the user is the user defined by the user variable.

Lines 25 through 36 perform precisely the same task imperatively, that is, through statements inside the method. The real work occurs in ImperativePermissionRequired , which creates an instance of the System.Security.Permissions.PrincipalPermission class, initializing the class with user and role . Line 54 invokes the Demand method. If the current principal is not the one indicated by user and role , an exception is thrown. In fact, both the declarative and imperative forms of security throw the identical exception, as shown in Figure 18.4

Figure 18.4. The SecurityException dialog that appears if the permission demand fails.

graphics/18fig04.gif

The only real difference between the two forms of usage ”declarative and imperative security ”of the PrincipalPermission class is when the permission is evaluated. With the declarative example the procedure is not permitted to run at all, whereas the imperative example permits the code to run up to the point that the PrincipalPermission.Demand method is invoked.

NOTE

Security attributes are implemented in terms of the security classes with the same name. For example, PrincipalPermissionAttribute is implemented in terms of the PrincipalPermission class. Whether you use the attribute or use the class directly, you are running the same code, thus resulting in the same behavior.

The Advantages of Declarative Security

Declarative security offers a few distinct advantages over imperative security.

  • While all security actions are codified as classes and attribute classes, every security action can be expressed declaratively. Some security actions like LinkDemands cannot be expressed imperatively.

  • Declarative security actions can be evaluated without running code since attributes are stored as part of an assembly's metadata; imperative security actions are stored as IL. This implies that imperative security actions can be evaluated only when the code is running.

  • Declarative security actions are checked immediately before a method is invoked, whereas imperative security actions may occur after a method has partially completed. The declarative security process prevents a method that will ultimately fail from wasting time.

  • A declarative security action placed at the class level applies to every method in the class. You must repeat imperative security actions for each method individually.

In general, declarative security has more advantages, but imperative security offers some benefits of its own. Let's take a moment to look at these.

The Advantages of Imperative Security

Imperative security actions run as lines of code intermixed with your application's code. This offers a couple of distinct advantages.

  • Because you write imperative security actions inside methods you can intersperse various security actions based on conditional logic. Declarative security yields an all-or-nothing approach to a security option.

  • You can pass dynamic arguments to imperative security actions. Declarative security actions require that you pass static values to these attributes as you write the declarative security code.

Both approaches offer benefits. It is worthwhile to evaluate whether to use declarative or imperative security in particular situations relative to the benefits each approach offers.



Visual Basic. NET Power Coding
Visual Basic(R) .NET Power Coding
ISBN: 0672324075
EAN: 2147483647
Year: 2005
Pages: 215
Authors: Paul Kimmel

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net