.NET and COM Security

I l @ ve RuBoard

.NET and COM+ Security

COM+ defines its own security mechanisms, mapping the identity of the client process to its own custom roles. The scheme used by .NET is similar, but it is implemented by the common language runtime. The System.EnterpriseServices namespace provides classes and enumerations that allow you to bridge the gap between the two systems. Before we look at how to implement COM+ security from managed code in a serviced component, it is worth reviewing the requirements and models used by .NET and COM+.

Code Access Security Requirements

Despite the fact that you use the .NET Framework Class Library to build serviced components , an application that instantiates a serviced component must be granted the UnmanagedCode privilege. This means that assemblies downloaded from the Internet, an intranet, or a local area network will not be able to instantiate serviced components unless they are explicitly trusted.

The .NET Role-Based Security Model

Chapter 2 described how .NET role-based security works. To recap, you can tag classes and methods with System.Security.Permissions.PrincipalPermissionAttribute , as shown here:

 /** @attribute PrincipalPermissionAttribute(SecurityAction.Demand,     Role="WONDERLAND\Bakers") */ /** @attribute PrincipalPermissionAttribute(SecurityAction.Demand,     Name="WONDERLAND\JSharp") */ public static short FeedsHowMany(short diameter, short shape,     short filling) {        } 

When an application executes the FeedsHowMany method, the common language runtime examines the identity of the process calling the method to ensure that it is either WONDERLAND\JSharp or a member of the WONDERLAND\Bakers role.

The .NET Framework Class Library also provides the System.Security.Permissions.PrincipalPermission class, which you can use to implement imperative security if you prefer. (See Chapter 2 for the details.)

The COM+ Role-Based Security Model

COM+ also provides role-based declarative security. COM+ security can be configured by an administrator through the Component Services console in Control Panel. An administrator can create roles and add Windows users and groups to those roles, as shown in Figure 14-18.

Figure 14-18. Adding users to roles in the Component Services console

Roles can be granted access to an entire component, specific interfaces, or individual methods. (You must first enable authorization in the COM+ application.) Figure 14-19 shows an example of granting the members of the FourthCoffee Staff COM+ role access to the CakeFactory component (and implicitly removing access for all other users).

Figure 14-19. Granting access to the members of the FourthCoffee Staff role

You can enforce security at the process level only or at the process and component level (the preferred option). At execution time, when a client application invokes a COM+ component, the COM+ runtime examines the identity of the client process and uses it to grant or deny access to the component, interface, or method. The frequency with which the client will be authenticated can be specified, ranging from once when the client first connects to the component to every time a packet of data is sent from the client to the COM+ application.

If a COM+ component requires access to secure resources, such as a DBMS, an administrator can configure the identity to be used. By default, the COM+ component will impersonate the caller, passing the identity of the caller to the resource manager. The caller must have been granted permission by the resource manager for this strategy to be successful. A preferred technique is to configure the COM+ application to run as a particular fixed identity. All access to resource managers will use this identity instead, which means that individual users do not have to be granted direct access.

Implementing COM+ Security from .NET

If you're building a serviced component, you can preconfigure much of the COM+ security information using attributes.

The System.EnterpriseServices.ApplicationAccessControlAttribute class allows you enable COM+ security and specifies the COM+ application-level security attributes such as the frequency of authentication and the impersonation level. You apply this attribute at the assembly level, as shown here:

 /** @assembly ApplicationAccessControlAttribute(true,    AccessChecksLevel=AccessChecksLevelOption.ApplicationComponent,    Authentication=AuthenticationOption.Packet,     ImpersonationLevel=ImpersonationLevelOption.Identify) */ 

The AccessChecksLevelOption, AuthenticationOption , and ImpersonationLevelOption enumerations contain values corresponding to each of the possible settings that an administrator can select when configuring a COM+ application manually.

To implement COM+ role-based security, you should define roles using SecurityRoleAttribute and secure components using ComponentAccessControl ­Attribute . (You should not use PrincipalPermissionAttribute .) You can use the SecurityRoleAttribute class to tag an entire assembly, a class, and individual methods. When a role is applied to an assembly, any user in the role will have access to every component in the assembly. When applied to a class or method, the security role will have access to that class or method only. The following example enables access control at the class level for the CakeFactory class, creates a COM+ role called Bakers , and then applies this role to the CakeFactory class. An administrator can then populate the Bakers role with users by using the Component Services console. (The Bakers role will initially be empty.) If you want to create multiple roles, you must apply SecurityRoleAttribute multiple times:

 /** @attribute ComponentAccessControlAttribute(true) */ /** @attribute SecurityRoleAttribute("Bakers") */ public class CakeFactory extends ServicedComponent implements ... { } 

If you examine the serviced component using the Component Services console and look at the security settings for the CakeFactory component, you'll see that authorization has been enabled and that the Bakers role has been created and applied to the CakeFactory component, as shown in Figure 14-20.

Figure 14-20. The security settings for the CakeFactory component

To secure a single method, you attach a SecurityRoleAttribute to the method as shown below. If you want to apply the same role to several methods, you must repeat the SecurityRoleAttribute for each method.

 /** @attribute SecurityRoleAttribute("Master Bakers") */ public ICake CreateCake(short size, short filling, short shape)  { } 

Note

If you implement method-level security, the .NET Framework will automatically create an extra role called Marshaler and attach it to the IDisposable and IManagedObject interfaces generated for the serviced component. This role allows clients to execute the methods defined by these interfaces. For example, if users need to execute the Dispose method, you should add them to the Marshaler role.


From our earlier discussions, you should recall that if you do not implement an interface, a serviced component will support only late binding and will not directly expose any methods to unmanaged COM+ clients. Therefore, you can provide method-level security only if you create serviced components that implement interfaces. However, rather confusingly, the SecurityRoleAttribute is applied to the method implementations in the serviced component, not to the method declarations in the interface!

COM+ Imperative Security

You can query security information programmatically and obtain details such as the account name used by the client that's executing code in a serviced component. The static property CurrentCall of the System.EnterpriseServices.SecurityCallContext class returns a SecurityCallContext object containing the security information relating to the current method call. The SecurityCallContext class itself defines a raft of additional methods and properties that you can use to determine whether security is actually enabled for the current context (the IsSecurityEnabled property), as well as determine the identities used by the process that's directly calling the serviced component ( DirectCaller ) and determine the process that originally made the method call ( OriginalCaller ). These might well be different.

The OriginalCaller and DirectCaller properties return a SecurityIdentity object, which contains information about the identity of the calling process, including the account name. The SecurityCallContext class provides the method IsCallerInRole , which you can use to determine whether the identity of the calling process matches a specified role. (The ContextUtil class also supplies IsCallerInRole as a static method). The IsUserInRole method allows you to specify an account name and a role and determines whether that account name is assigned to the role.

You can use this information to control access to sensitive code sequences in a method of a serviced component, which gives you a finer degree of control than can be achieved using declarative security alone. For example, in the CreateCake method shown below, declarative security attributes limit access to members of the Master Bakers group . The code examines the details of the original caller, and if the identity is WONDERLAND\JSharp (a newly recruited master chef who needs close monitoring), the method will write a record to the Windows event log recording the date and time the cake was created.

 /** @attribute SecureMethodAttribute() */ /** @attribute SecurityRoleAttribute("Master Bakers") */ public ICake CreateCake(short size, short filling, short shape)  {    SecurityCallContext context = SecurityCallContext.get_CurrentCall();    if (context.get_IsSecurityEnabled())    {       SecurityIdentity caller = context.get_OriginalCaller();       if (caller.get_AccountName().Equals("WONDERLAND\JSharp"))       {          System.Diagnostics.EventLog appLog =             new System.Diagnostics.EventLog("Application", ".",             "Fourth Coffee");          String logMessage = "WONDERLAND\JSharp is creating a new cake. "           + DateTime.get_Now();          appLog.WriteEntry(logMessage,             System.Diagnostics.EventLogEntryType.Warning);       }    }    // Create the cake     } 
I l @ ve RuBoard


Microsoft Visual J# .NET (Core Reference)
Microsoft Visual J# .NET (Core Reference) (Pro-Developer)
ISBN: 0735615500
EAN: 2147483647
Year: 2002
Pages: 128

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