This is why CanWriteProperty() is virtual, so you can add extra rules beyond smiple role checks to your property-level authorization.
You may also add checks in your factory (or DataPortal_Fetch()) methods to prevent the wrong user from retrieving an object they shouldn't see.
Obviously the per-type authorization can't handle this, because we're talking about instance-level values.
The way I've handled this type of situation may be more complicated and a bigger change than you want, so definitely go with the simplest option that works for you.
In my case, my security model resolves to the individual permission/privilege/right (synonyms - all depends on who you are talking to). To manage organizational needs, I have "borrowed" the concept of Privilege Depth from Microsoft CRM's security model where a user may have been assigned a certain privilege, such as "May edit departments," but the final answer depends on their depth which can be one of the following:
When you combine the privilege with depth, you get tremendous control over who can do what. Best bet, if you want to know more, is to do a web search on "Microsoft CRM Security".
HTH
I have an external security manager object that resolves the request. So, my CanXYZProperty method, for instance, would delegate to the SecurityManager.HasPermission() method passing in the appropriate arguments. I have two scenarios that I use: simple privileges or complex/specific privileges.
In the latter case, privileges are very detailed, usually one privilege per operation. I find this most prevalent in service apps. So, the app could have privileges like "Can Check-Out Projects", "Can Assign Resources" and so on.
In this case, for general inquiries, the only argument is the privilege being checked and authorization is simply checking if the user has that permission at that depth.
For per-instance checks, the object and the permission are passed and the state of the object can be evaluated to make sure that the user can perform the operation. This is governed by additional rules such as ownership and assignment (ie, a user can't edit an object when it's been assigned to someone else).
With this approach, per-type authorization really doesn't apply.
On the other hand, with simple Read, Edit, Delete privileges, these can be granted on a per-type basis. When I do this, authorization is granted when the user has the desired privilege on the specified type. For instance, per-type authorization would answer a question like: "Can this user edit Products?"
Likewise, for per-instance checking, we first check based on the object's type then apply the additional rules to make sure that can perform the operation on that specific object. This answers the question "Can this user edit THIS Product?"
Make sense? HTH
SonOfPirate:I have an external security manager object that resolves the request. So, my CanXYZProperty method, for instance, would delegate to the SecurityManager.HasPermission() method passing in the appropriate arguments. I have two scenarios that I use: simple privileges or complex/specific privileges.
...
In this case, for general inquiries, the only argument is the privilege being checked and authorization is simply checking if the user has that permission at that depth.
For per-instance checks, the object and the permission are passed and the state of the object can be evaluated to make sure that the user can perform the operation. This is governed by additional rules such as ownership and assignment (ie, a user can't edit an object when it's been assigned to someone else).
This sounds very similar to our requirement. We can't use the type-based roles as is because the object itself must be inspected to determine if the privilege applies (e.g. your depth concept).
Are you using the CSLA role mechanism at all or is your implementation completely separate?
It is based on the CSLA implementation. We have an additional interface (IUser) that our custom principal implements. This interface defines the Privileges property which returns the list of privileges granted to the user (pulled from the db). Then we've added a layer on top of the authorization code to allow the per-instance rules to be applied.
We still have the role-based methods in place, so if we wanted we could simply check for the role. But, since our roles are dynamic and user-defined, it doesn't make any sense in most of applications to hard-code roles into the business objects. A finite set of privileges does the job.
In the database, we relate each role to the privileges associated with it and the depth. So, for instance, the "Project Manager" role is granted the "Can Create Projects" privilege at the Local depth while "Development Managers" are granted the same right at the Deep depth.
Our authorization methods check for role membership when a role (string) is passed. Overloaded methods accept the privilege (custom object) and, optionally, the depth (enum) and checks for the specific permission at the given depth. Another set of overloads takes the business object as an argument, delegates to the other methods for the Privilege Check then applies the additional logic to authorize access to the specific object.
I hope that answers your question.
There is no support for instance-level auth rules in CSLA.
I expect any instance-level rules would be in the factory
methods and/or an override of Save().
Rocky
From: ajj3085
[mailto:cslanet@lhotka.net]
Sent: Monday, July 28, 2008 12:23 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Changing authorization based on role &
property value?
Ok, that's what I thought the answer would be.
My only hesitation was because of the Instance-level authorization rules.. that
would be the other place I suspect this could work, and I thought I was missing
something by not seeing how it would work with those kind of rules.
So I guess the question is.. when would you ever use instance-level
authorization rules? It seems like you either never would.. or there's
some very niche place for them I don't see.
Thanks!
Andy
Those are per-property authorization that are customized
per-instance.
They are really a hold-over from the poor 2.0 implementation,
and I don’t recommend their use. Xal tried to argue me into removing
them, and I think he was right, but that’s all water under the bridge at
this point.
Rocky
From: ajj3085
[mailto:cslanet@lhotka.net]
Sent: Monday, July 28, 2008 1:49 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Changing authorization based on role &
property value?
Ok... then I'm really confused.. because I see these methods
on Csla.Security.AuthorizationRules:
InstanceAllowExecute(string, params string[])
InstanceAllowRead(string, params string[])
InstanceAllowWrite(string, params string[])
InstanceDenyExecute(string, params string[])
InstanceDenyRead(string, params string[])
InstanceDenyWrite(string, params string[])
So by support do you mean those methods are hold-overs from previous versions,
or that they should be removed (or have already been removed in the latest
beta)?
These method signatures are from Csla 3.5.0.
Andy
Copyright (c) Marimer LLC