Team LiB
Previous Section Next Section

Security in COM+

Security in COM+ is an extremely complex and involved topic. If you really want the full details, you should pick up a book devoted to COM+. The next section will provide you with an overview of how security works in a COM+ application, the security options available to you, and how you can program against that security model.

Object and Security Contexts

A security context identifies the principal (see other chapters in this book about IPrincipal and IIdentity) that is performing a given action. If a method is being invoked on a serviced component, COM+ can be configured to provide that component with an object context. That context gives the code the capability to query the identity of the calling client as well as the roles (discussed shortly) to which the user belongs. The object context allows a method on a ServicedComponent to obtain information about current transactions, whether security is enabled, and allows the code to vote for the commitment or rollback of the current transaction.

Table 40.1 is a quick list of some of the methods and properties available on the ContextUtil class, a class used for interfacing with the MTS (COM+) context object.

Table 40.1. Methods and Properties of the ContextUtil Class

Property / Method

Description

Properties

ActivityId

Gets the GUID for the current activity

ApplicationId

Gets the GUID for the current COM+ application

ContextId

Gets the GUID for the current context

DeactivateOnReturn

Indicates to the COM+ system that the component will be deactivated when the current method finishes

IsInTransaction

Indicates whether the current method is participating in a transaction

IsSecurityEnabled

Indicates whether security is enabled at the component or process level

transaction

Returns information about the current distributed transaction

transactionId

Gets the GUID for the current transaction

Methods

DisableCommit()

Disables transaction commits for the current method execution

EnableCommit()

Enables transaction commits for the current method execution

GetNamedProperty()

Gets a named property that belongs to the current object context; not to be confused with shared property groups

IsCallerInRole()

Indicates whether the client code's security context is within a certain COM+ role

SetAbort()

Votes to abort (roll back) the current transaction

SetComplete()

Votes to commit (complete) the current transaction


Role-Based Security

Role-based security refers to the concept of assigning roles or groups to specific users. What the user can and cannot do is dictated by the roles to which that user belongs.

Every COM+ application has a set of roles associated with it. These roles can then have user accounts or user groups placed in them. These accounts are part of an NT domain or part of an Active Directory. Therefore, you can create roles such as Finance, Shipping, Receiving, Billing, Administrators, and Users. Each of these groups could have different or overlapping members. Code within the COM+ application can then test whether the user belongs to a particular group before allowing the user to perform a given action.

The code in Listing 40.3 shows a new class, RoleSecurity, that has methods whose use is restricted to specific roles within the application. The code is examined in more detail after the listing.

Listing 40.3. A Class That Has Methods That Utilize Object and Security Contexts
   using System;
   using System.EnterpriseServices;

   namespace ServicedApplication
   {
     /// <summary>
     /// Summary description for RoleSecurity.
     /// </summary>
     [ComponentAccessControl(true),
      SecurityRole("App User", true),
      SecurityRole("App Administrator")]
     [Transaction(TransactionOption.Required)]
     [EventTrackingEnabled(true)]
     [JustInTimeActivation(true)]
     [Synchronization( SynchronizationOption.Required)]
     public class RoleSecurity : ServicedComponent
     {
       public string PerformAdministrativeAction()
       {
         if (!ContextUtil.IsSecurityEnabled)
           return "No Security Available";

         if (SecurityCallContext.CurrentCall.IsCallerInRole("App Administrator"))
         {
           return "Task Completed";
         }
         else
         {
           return "Task Failed";
         }
       }
       public string PerformStandardAction()
       {
         if (!ContextUtil.IsSecurityEnabled)
           return "No Security Available";

         if (SecurityCallContext.CurrentCall.IsCallerInRole("App Administrator") ||
             SecurityCallContext.CurrentCall.IsCallerInRole("App User"))
         {
           return "Task Completed by " +
             SecurityCallContext.CurrentCall.DirectCaller.AccountName;
         }
         else
           return "Task Failed";
       }
     }
   }

The onslaught of attributes at the top of the class defines the necessary COM+ configuration that is required for COM+ to provide the component with security and object contexts. The SecurityRole attribute is used so that when the assembly is self-registering with COM+, it will create those security roles. If a Boolean value of true is supplied for this attribute, it will automatically add the special group Everyone to the role.

The first method, PerformAdministrativeAction , makes a call to IsCallerInRole to find out whether the calling client code's security context is in the administrative application user role. The second method will let anyone execute it so long as they are a user or an administrator.

The console output from invoking both of these methods is as follows:

Administrative result: Task Failed
Standard result: Task Completed by SILVERALIEN\Kevin Hoffman

By default, the Kevin Hoffman account is not part of the administrators group, but because the special group Everyone is part of the standard users group, the second task was completed. To illustrate how to identify the calling client, the name of the user that requested the task is displayed.

    Team LiB
    Previous Section Next Section