Skip navigation

Protecting Resources with Permission Objects

Clarify, Don’t Conflict

Secure ASP.NET

LANGUAGES: ALL

ASP.NET VERSIONS: 1.1

 

Protecting Resources with Permission Objects

Clarify, Don t Conflict

 

By Don Kiely

 

One of the things that wasn t initially clear to me about CAS permissions is that they are used in two basic ways: 1) to protect resources, and 2) to determine whether calling code has the permission it needs to access the protected resource. Without keeping that distinction crystal clear, permissions can be a sticky morass of seemingly conflicting details. Fortunately, most of the code that goes into custom .NET applications is not protecting a resource directly, so you can focus your efforts on one use of permissions.

 

In this installation of columns about .NET permissions, I ll look at using permission classes to protect resources. Next time I ll look at the other side namely, how to make the calling code handle permission requirements gracefully.

 

System.Security.CodeAccessPermission is the mother of most permission objects in .NET, so we ll start there to develop an understanding of how permissions can protect a resource. It has three broad groups of methods you can use:

  • Resource protection, such as Assert, Demand, and Deny. These methods specify how far up the call stack the code has the specified permission. More about these later in this column.
  • Permission set manipulation, such as Intersect, IsSubsetOf, and Union. These methods let you hook into security policy that defines multiple permissions to extract another permission set. I ll delve into these in a future column.
  • Other generic object methods, such as Copy and ToString. These are the methods that are incidental to the CodeAccessPermission class as a .NET object. I ll not explore these any further since they are not directly related to code access security.

 

Keep in mind, of course, that permission objects that derive from CodeAccessPermission can and do add to this basic interface.

 

The most important part of the CodeAccessPermission interface, as well as for other permission objects, is that they implement the IPermission interface. IPermission requires implementations of the Copy, Demand, Intersect, IsSubsetOf, and Union methods, then build on that minimal interface.

 

Let s say that you re writing a Web application that makes use of your company s highly sensitive and secret algorithms for finding out who is a person s secret Santa. This is highly privileged information obviously! so you want to allow only the elite members of the SecretSantaAdmin group on the domain to have access to the information. Furthermore, this information is SO secretive that you practice defense in depth and implement Windows-integrated security for the ASP.NET application, but you also need to make sure that the GetSecretSanta method can be executed only by the admin group.

 

The code to protect the secret algorithms is actually very simple. This is the complete GetSecretSanta method, which takes an employee name as input and returns that person s secret Santa:

 

Private Function GetSecretSanta(ByVal sEmpName As String) As String

 Dim pp As New PrincipalPermission(Nothing, "RIVERCHASER\SecretSantaAdmin")

 pp.Demand()

 'Do the secret stuff

 Dim sSanta As String

 Select Case sEmpName

   Case "Carol"

      sSanta = "Don"

   Case Else

      sSanta = "Sorry! No Santa for that employee!"

 End Select

 Return sSanta

End Function

 

The important part of the code is these two lines:

 

Dim pp As New PrincipalPermission(Nothing, "RIVERCHASER\SecretSantaAdmin")

pp.Demand()

 

The first line instantiates a System.Security.Permissions.PrincipalPermission class. This permission class does not derive from the CodeAccessPermission class because it interacts directly with the Windows security system. The first parameter in the constructor used here takes a user name and the second is either a local or domain group name. You can specify either parameter or both, so here the code uses Nothing for the user name and a string for the domain (RIVERCHASER) group.

 

After the permission object is instantiated, the call to the Demand method is the step that enforces that this method is runable only by members of the specified group. At this point the Common Language Runtime (CLR) makes sure that the code is running by a member of the specified group. If it isn t, the code throws a catchable SecurityException with a message Request for principal permission failed. Robust applications would, of course, catch that exception and handle it in some way.

 

You can do the same sort of demand declaratively using a method attribute:

 

<PrincipalPermissionAttribute(SecurityAction.Demand, Role:="RIVERCHASER\SecretSantaAdmin")> _

Private Function GetSecretSanta(ByVal sEmpName As String) As String

 

In this case, you can use named parameters in VB.NET to avoid passing Nothing as the user name.

 

And that s all there is to it! The secrets of the secret Santa are safe for another year.

 

Next time I ll explore how to interact with permissions from the calling code s point of view, then follow up with an exploration of stack walks.

 

Don Kiely is senior technology consultant for Information Insights, a business and technology consultancy in Fairbanks, AK. E-mail him at mailto:[email protected].

 

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish