Niclas Hedhman wrote:

Gang,
Maybe this has been discussed before, but I haven't seen it for quite a while, so I start with a blank piece of paper.


Security Protection Mechanism is about a simplified way for all components to protect objects, methods, resources and so on. The Protection Mechanism should support both "trusted system components" as well as "non-trusted users" and everything in between.

I have been thinking a little bit about this recently, and would like to get it going;

My very short Wish-list
1. Codebase security a la standard Java security policies, to fulfill the "trusted system components" vs "untrusted system components" difference.


2. Subject level security, leveraging the JAAS, for User based authorization at any granularity.

3. Ease-of-Use for both Component Author and Component User. Very little code should be required by each of these groups.

4. Pluggable architecture for the management of users, roles and rights, to allow for simple authorization systems or all the way to DB driven ones. Neither the component author nor the component user should need to worry about what authorization system that is in place.



Good wish list. Basic stuff that is needed.


I have been drawing on a piece of paper for quite a while now, and the "cleanest" (IMHO) way I see it happening is to introduce support for it in Framework. The strong argument would be that security is (or should be for all non-M$ apps) a very central piece of concern;


public interface SecureServiceManager extends ServiceManager
{
   Object lookup( String role, Object securityContext );

   // returns a securityContext, i.e. an javax.security.auth.Subject
   // instance. Not sure if it is a security risk to return the Subject
   // to the caller. Need to be investigated.
   Object login( CallbackHandler callback );

   void logout( Object securityContext );
}

and the corresponding

public interface SecureServiceable
{
   void service( SecureServiceManager manager );
}

BUT, one could harness the Context as well, so that the "User Code" would be something like;

public void contextualize( Context context )
{
SecureServiceManager secman = (SecureServiceManager) context.get( "avalon.security.servicemanager" );
// and so on...
}


It doesn't look as neat, and I suggest we keep that debate separately. Below is showacse of the use with the introduction of SecureServiceManager.


#*&!$* spit!


Just put the security context into a thread local variable. Typically this is going to be a principal. The service manager implementation can handle the determination if pricipal is required or not - and do the autentication and access contol if required.



Let's look at "use-case" part;

The service that contains the protected operations should be fairly simple to write.

public interface MyService
{
   void doSomeOperation();
}

public class MyComponent extends AbstractLogEnabled
   implements MyProtectedService
{
   private Permission m_RequiredPermission;

   public MyComponent()
   {
       m_RequiredPermission = new WhatEverPermission( "ForInstanceAName" );
   }

public void doSomeOperation()
{
AccessController.checkPermission( m_RequiredPermission ); // :
// :
}
}



Method level access control could be moved to the proxy. I.e. no need to do AccessController.checkPermission - we can takie care of that automatically using metadata available on the container side of the equation.


<snip>

IMHO, the above use-case is "really clean" :o)


But could be cleaner! But thatr's what your hinting at below isn't it?

Minimal amount of work for both the component author and the component user.


Which could be reduced to zero.



The above scenario is nice, BUT doesn't it only covers part of the problem, i.e. protecting a particular method?
What about I need to protect individual objects or resources, based on users??


The establishment of the AccessControlContext in Merlin, will provide full protection to everything, so by creating sophisticated Permission classes, I can practically protect according to any strategy, for instance;

Let's say I want to protected a persisted database object.

public class MyValueObject
{
   private String m_PrimaryKey;
   private String m_Name;
   private String m_Description;
   private Collection m_Widgets;

   public MyValueObject()
   {}

   public String getPrimaryKey()
   {
       return m_PrimaryKey;
   }

public String getName()
{
DatabasePermission perm = new DatabasePermission( m_PrimaryKey + ".name", "read" );
AccessController.checkPermission( perm );
return m_Name;
}


public void setName( String name )
{
DatabasePermission perm = new DatabasePermission( m_PrimaryKey + ".name", "write" );
AccessController.checkPermission( perm );
m_Name = name;
}


public String getDescription()
{
DatabasePermission perm = new DatabasePermission( m_PrimaryKey + ".description", "read" );
AccessController.checkPermission( perm );
return m_Description;
}


public void setDescription( String descr )
{
DatabasePermission perm = new DatabasePermission( m_PrimaryKey + ".description", "write" );
AccessController.checkPermission( perm );
m_Description = descr;
}


public Collection getWidgets()
{
DatabasePermission perm = new DatabasePermission( m_PrimaryKey + ".widgets", "read" );
AccessController.checkPermission( perm );
ArrayList clone = new ArrayList( m_Widgets );
return clone;
}


public void addWidget( Widget widget )
{
DatabasePermission perm = new DatabasePermission( m_PrimaryKey + ".widgets", "add" );
AccessController.checkPermission( perm );
m_Widgets.add( widget );
}


public void removeWidget( Widget widget )
{
DatabasePermission perm = new DatabasePermission( m_PrimaryKey + ".widgets", "remove" );
AccessController.checkPermission( perm );
m_Widgets.remove( widget );
}
}



Imoportant question - how much of this can be moved to metainfo on methods?




But then you would need to create some fairly fancy DatabasePermission class, which understand how permissions granted would imply access or not according to the permissions required. This is bringing us over to the Authorization Management, which is outside the scope of this RT (see below). However, it is important to notice that the DatabasePermission above, is therefor NOT a good solution, since it ties the compont to tightly to a particular Authorization Management system (DB).



Now, back to Merlin and how to implement this;


Each lookup in the SecureServiceManager, needs to make sure that the security context is the same, otherwise instantiate a new Proxy (!), but not necessarily a new component.

The ApplianceInvocationHandler would need to wrap the whole call with something like this (Exception handling left out);

public Object invoke( final Object proxy,
               final Method method,
               final Object[] args )
               throws Throwable
{
   MyAction action = new MyAction( m_Instance, method, args );
   return Subject.doAs( m_Subject, action );
}

private class MyAction
   implements PrivilegedAction
{
   private Method m_Method;
   private Object m_Instance;
   private Object[] m_Args;

   PrivilegedAction( Object instance, Method method, Object[] args)
   {
       m_Instance = instance;
       m_Args = args;
       m_Method = method;
   }

   public Object run()
   {
       return m_Method.invoke( m_Instance, m_Args );
   }
}


And then we would need a new SecureSecurityManager and understand the SecureServiceable interface signature...



Ummm, not sure - should be able to handle this without distrupting interfaces or supply info to the component.



Believe it or not, but I have only cover ONE out THREE issues with user based authorization, namely the Protection Mechanism.


We need to work out 1. Security Configuration, i.e. the pluggable system of components making up the complete security system.
2. Standardized Authorization Management, i.e. standardized way to manage "Who can do What", how to add/remove/edit/audit users, roles and rights.



Ok, that's about it for now... How do you all feel about this subject?? I hope you are not in M$ mood ;o)



:-)


Sounds good, corresponds to the roadmap, and fits with immediate interests in building the plugable facilities side of things for container profiling.

Cheers, Steve.

Cheers,
Niclas

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





--


Stephen J. McConnell
mailto:[EMAIL PROTECTED]

|------------------------------------------------|
| Magic by Merlin                                |
| Production by Avalon                           |
|                                                |
| http://avalon.apache.org/merlin                |
| http://dpml.net/                               |
|------------------------------------------------|





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to