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.
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
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
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.
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.
The default provider in CSLA simply returns principal.IsInRole(role), but you could write a provider like
{
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;
}
Rocky
=================================================================
Joe
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.
Copyright (c) Marimer LLC