Security that isn't role based

Security that isn't role based

Old forum URL: forums.lhotka.net/forums/t/5413.aspx


Wbmstrmjb posted on Tuesday, September 16, 2008

Our security model is such that Users are assigned Roles and Roles have Permissions.  Each Permission has CRUD.  The IsInRole does not work for our model because it will be based on whether they have a particular CRUD piece of a Permission and not whether they are in a particular Role.  How can we still use CSLA's security to implement this model?

rsbaker0 replied on Tuesday, September 16, 2008

We have almost exactly the same permission model, but unfortunately I don't really see a good way to remap this to the CSLA implementation.

I think Rocky said you could safely retask your "permissions" as roles, but the CSLA security model seems (at least to me) to be primarily centered around property access, and what we really need is task or function access.

So, I've basically rolled my own implementation for the time being -- essentially I have a BitArray property in my user object where each permisssion is mapped to a single bit, which makes for both compact storage and efficient testing. I still have all the CanReadProperty()/CanWriteProperty() calls generated in my BO layer, but they are currently NOPS.

triplea replied on Wednesday, September 17, 2008

The way I have implemented this (I think its similar) is place a method bool HasPermission(string operation) on my custom Identity. When a user gets authenticated, a list of valid permissions for the users role(s) gets loaded internally (I use strings for now but a bit array as mentioned or any other form would do the trick). Then I place the checks all over my BO's so for example:

public static bool CanAddObject()
{
      return ((CustomIdentity)Csla.ApplicationContext.User.Identity).HasPermission("AddCustomer");
}

I used this as a guide: http://forums.lhotka.net/forums/thread/17224.aspx

HTH

tmg4340 replied on Wednesday, September 17, 2008

CSLA's permission model is actually built around .NET's model - it's intended to integrate with the existing Principal/Identity system.  As such, "IsInRole" is defined under that system, not CSLA.  If you look at BusinessPrincipalBase, it's just an implementation of .NET's IPrincipal interface.

Having said that, the solutions presented here will work, and there's certainly nothing wrong with them.  But you could do something that would integrate with "IsInRole".  IIRC, the PT example creates a CSLA business object to use for its IIdentity implementation (which is where the list of roles and the actual "IsInRole" implementation lies).  Even if it doesn't, it's certainly a possibility - .NET relies on those two interfaces to do its work, so you could use BusinessPrincipalBase, create a CSLA RO BO that implements IIdentity, plug them in, and have at it.

So... how can you integrate that with your role/permission model?  Remember that "IsInRole" takes a string value.  That string value can pretty much be anything you want - just because the method name references roles doesn't mean your actual role string has to be limited to that.  So you could create your list of roles as a concatenation of role/permission, and make your calls that way.

(And to the poster who talked about needing task/function access - starting with 3.0, the authorization rules system implemented methods for allowing/denying the execution of methods.  And I believe that the 3.5 techniques to standardize the "Can" methods have a "CanExecute"...)

HTH

- Scott

stanc replied on Wednesday, September 17, 2008

This is exactly what we have. To make things work with the CSLA model we did as Scott suggested. I thought it might be helpful to provide an example of what we did.

When authenicating the user, we get their individual permissions and add the appropriate CSLA roles. It doesn't matter what roles (from our app) the users belong to, it's their end permissions that determine the CSLA roles.

The CSLA roles are a combination of the BO (name) and the CRUD operation. Say we have an Order object and we wanted to set permissions for CRUD operations. Using CSLA we would have roles called "OrderCreate", "OrderRead"...

So we can have a user (Bob), who belongs to two application roles (User and Checker). User may have CR permissions for Order and Checker may have UD permissions, so Bob would have the full CRUD permissions for Order. When he is authenticated he will have the following CSLA roles "OrderCreate", "OrderRead", "OrderUpdate", and "OrderDelete".

This allows us to have as many different custom application roles we want with different permission settings, and allows our users to be tied to more than one application role as well. In the end, our BO will check against the CSLA roles that are figured out during the authenication process.

Hope this was clear and helpful.

JoeFallon1 replied on Wednesday, September 17, 2008

One thing that has not been mentioned yet is a new feature that Rocky added to the framework in 3.5 to support using something other than IsInRole. He now allows you to add a setting to your config file describing your provider. So I can use HasPermission directly instead of IsInRole.

===================================================================
Rocky wrote:
http://forums.lhotka.net/forums/thread/20749.aspx

The object-level auth works like the property-level – which is to say that if you don’t specifically allow/deny any roles then all roles are allowed. The default is permissive.

 Regarding the HasPermission() thing – I finally implemented something Joe asked for a long time ago. You can now provide a replacement behavior for IsInRole() deep within CSLA. This is a provider model concept, where you write an IsInRole provider that (if I remember right) looks like this:

 void IsInRole(IPrincipal principal, string role) 

The default provider in CSLA simply returns principal.IsInRole(role), but you could write a provider like

 public static void IsInRole(IPrincipal principal, string role)
{
  PTPrincipal.HasPermission(role);
} 

Or 

public static void IsInRole(IPrincipal principal, string role)
{
  var p = principal as MyCustomPrincipalType;
  if (p != null)
    return p.HasPermission(role);
  else
    return false;
}

 Or whatever you need. Then you just add an entry in the app.config file to tell CSLA to load this custom provider and away you go. 

Rocky

=================================================================

Joe

rsbaker0 replied on Wednesday, September 17, 2008

Is there any reason to be concerned about using the CSLA model if you have a large number of different permissions (say 300+), or should I not worry about this?

This was one reason I went with a BitArray implementation -- 300 strings seemed like a lot of baggage to be ferrying back and forth in addition to everything else that is going on.

rasupit replied on Wednesday, September 17, 2008

It's been several years since I implemented object level security.  I'm still using this implementation on all our web development.  This is the last link I can find on this forum.

There has been very little changed but the concept is still the same.  I included the CanGet|Add|Edit|DeleteObject in the base class as follow:

        public static bool CanGetObject()
        {
            return SecurityManager.CanGetObject(typeof(T));
        }

Copyright (c) Marimer LLC