- Home
- General
- General Chat
Authorization support
Joined: 29-Jul-2005
Do you have any plans in 2.vNext to support entity authorization? By default I would like to see support for View(instantiation)/Add/Edit/Delete. As a bonus property level authorization and method (task) level would be a bonus.
Generally I would add permission demand attributes however with your Entity design, espesially for adapter that isn't really viable.
??
Thanks, BOb
Joined: 17-Aug-2003
As authorization can be done in a lot of ways, we think it's best to add tap-in methods like OnBeforeFieldValueGet and OnAfterFieldValueGet etc., so you can add authorization code there. As an addition to the already available set of methods.
For example, you talk about attributes, but I've read in threads here that others think in the direction of method call intercepts.
If you would like to elaborate more about what the bare minimum needs are for your way of adding authorization we can check if we need to make small or large changes for these to allow you to add these.
What we'd like to add is facilities so developers can add code easily which checks if the current USER is allowed to perform an action. Another way of authorization could be target towards developers. We don't see that as a valuable point as that's more of a team problem.
V2.1 development starts later in december. Currently I'm busy writing a .lgp merge tool so people can work in teams with a master and copies of the .lgp file and merge changes This should be out later in december. When v2.1 dev starts we'll open a forum where discussions like with the v2.0 development can take place.
Joined: 15-Oct-2004
Otis wrote:
As authorization can be done in a lot of ways, we think it's best to add tap-in methods like OnBeforeFieldValueGet and OnAfterFieldValueGet etc., so you can add authorization code there. As an addition to the already available set of methods.
The tap-in method calls are coming in v2.1 or will they be available before?
Joined: 29-Jul-2005
Otis wrote:
As authorization can be done in a lot of ways, we think it's best to add tap-in methods like OnBeforeFieldValueGet and OnAfterFieldValueGet etc., so you can add authorization code there. As an addition to the already available set of methods.
For example, you talk about attributes, but I've read in threads here that others think in the direction of method call intercepts.
Ok, doesn't really matter to me if it is done explicitly or implicitly (as MS docs call it) what I guess I am mostly looking for is a way to protect the common items without writting code. Since LLBLGen is a code generator I want to leverage that by putting in the role name into the designer for those "common" items. In addition to that I know that I can add code to my own methods since I am writting them.
I also would expect this to use the built in security in the .Net fw, in that the code asks the CurrentPrinciple on the current thread if the user is in the Role.
When I say common items I am refering to the following with an Entity:
Entity Instantiation - If the user doesn't have this role then a security exception is thrown when trying to New up the object. Could be a principle demand at the class level or a role check in the constructor, doesn't matter to me.
Entity New - SecurityException is thrown if the user tries to save a new entity or maybe when trying to add an Entity to a collection Entity Edit - SecurityException is thrown if the user tries to save a dirty entity Entity Delete - SecurityException is thrown if the user tires to delete an entity
each Property - The user would not be able to access the property. A security exception would be good. But, and option to decide if you get an exception or the property just returns Nothing/Null and doesn't set the field would be nice... some people may prefer this.
There is also some argument here as to whether a user should be able to add an entity if they don't have the edit permission. So, you may need an option there.
In addition to this, it would be nice to be able to specify some type of naming convention so the designer would create the names automatically for me... for example....
Role required to instantiate entity: ${EntityName}Read Role required to add new entity: ${EntityName}New Role required to edit entity: ${EntityName}Edit Role required to delete entity: ${EntityName}Delete Role required for property: ${EntityName}${PropertyName}Access
If these config items were blank they wouldn't be generated. If they weren't blank they would be used to populate the values in the designer that were blank. If there were values in the designer for each entity/property those would be used.
Otis wrote:
If you would like to elaborate more about what the bare minimum needs are for your way of adding authorization we can check if we need to make small or large changes for these to allow you to add these.
So, the above would be the minimum perhaps structure.
Otis wrote:
What we'd like to add is facilities so developers can add code easily which checks if the current USER is allowed to perform an action. Another way of authorization could be target towards developers. We don't see that as a valuable point as that's more of a team problem.
As you say above a great extension would be to allow for an API in the Entities that the UI tier could interogate to determine how to display the UI elements. For example, only display the Add button if the user has the EntityNew permission. One other framework I have worked with has implemented this with a series of Allow??? methods/properties. Such as:
AllowAdd(), AllowEdit(), AllowDelete()
I see an advantage to having these be static and instance. If they are static I can just do code like:
addButton.Visible = Customer.AllowAdd()
The advantage to them being overrideable instance methods would be that I could add record level checks to them. For example a user may only be able to delete certain customers so I could put code in my AllowDelete() that would do something like:
if (IsInRole(ROLE_Manager) && this.KeyAccount) return (true && base.AllowDelete()); else return false;
Of course in this case your save/delete code would just call the instance's AllowDelete() before doing a delete and throw a SecurityException (or whatever).
Hope this helps. Love to hear others comments on this.
BOb
Joined: 17-Aug-2003
PilotBob wrote:
Otis wrote:
As authorization can be done in a lot of ways, we think it's best to add tap-in methods like OnBeforeFieldValueGet and OnAfterFieldValueGet etc., so you can add authorization code there. As an addition to the already available set of methods.
For example, you talk about attributes, but I've read in threads here that others think in the direction of method call intercepts.
Ok, doesn't really matter to me if it is done explicitly or implicitly (as MS docs call it) what I guess I am mostly looking for is a way to protect the common items without writting code. Since LLBLGen is a code generator I want to leverage that by putting in the role name into the designer for those "common" items. In addition to that I know that I can add code to my own methods since I am writting them.
I also would expect this to use the built in security in the .Net fw, in that the code asks the CurrentPrinciple on the current thread if the user is in the Role.
When I say common items I am refering to the following with an Entity:
Entity Instantiation - If the user doesn't have this role then a security exception is thrown when trying to New up the object. Could be a principle demand at the class level or a role check in the constructor, doesn't matter to me.
I think this is way too fine grained to be practical. In theory it might sound OK, but isn't it so that the instance you're creating is essential for the routine you're in? So i.o.w.: if the user doesn't have the right security rights, it can't use the routine, so the security check should be on the routine.
Entity New - SecurityException is thrown if the user tries to save a new entity or maybe when trying to add an Entity to a collection Entity Edit - SecurityException is thrown if the user tries to save a dirty entity Entity Delete - SecurityException is thrown if the user tires to delete an entity
I think this is different from above, as this is the result of an action in a routine which can fail in so many ways also, so a security check can also be a reason for failure. However, how can this not be solved with a validation object ?
each Property - The user would not be able to access the property. A security exception would be good. But, and option to decide if you get an exception or the property just returns Nothing/Null and doesn't set the field would be nice... some people may prefer this.
I was thinking of adding tap in code for this. As the concept of a 'user' is unclear, undefined and not in the scope of llblgen pro code: is it a windows user, a user of your own role system, an asp.net user / role ? etc.
There is also some argument here as to whether a user should be able to add an entity if they don't have the edit permission. So, you may need an option there.
In addition to this, it would be nice to be able to specify some type of naming convention so the designer would create the names automatically for me... for example....
Role required to instantiate entity: ${EntityName}Read Role required to add new entity: ${EntityName}New Role required to edit entity: ${EntityName}Edit Role required to delete entity: ${EntityName}Delete Role required for property: ${EntityName}${PropertyName}Access
If these config items were blank they wouldn't be generated. If they weren't blank they would be used to populate the values in the designer that were blank. If there were values in the designer for each entity/property those would be used.
What's 'Role' in this context?
Otis wrote:
If you would like to elaborate more about what the bare minimum needs are for your way of adding authorization we can check if we need to make small or large changes for these to allow you to add these.
So, the above would be the minimum perhaps structure.
I don't see anything that can't be done by tap-in method overrides. The thing is: there are so many ways of doing this, that any chosen path is not useful for users of another chosen path and as this is code that is at the edge of the scope of the framework (but by its nature it's natural to place it inside the scope) it's IMHO best to offer the hooks, the place where code has to be added, and that addition has to be flexible and easy.
Otis wrote:
What we'd like to add is facilities so developers can add code easily which checks if the current USER is allowed to perform an action. Another way of authorization could be target towards developers. We don't see that as a valuable point as that's more of a team problem.
As you say above a great extension would be to allow for an API in the Entities that the UI tier could interogate to determine how to display the UI elements. For example, only display the Add button if the user has the EntityNew permission. One other framework I have worked with has implemented this with a series of Allow??? methods/properties. Such as:
AllowAdd(), AllowEdit(), AllowDelete()
I see an advantage to having these be static and instance. If they are static I can just do code like:
addButton.Visible = Customer.AllowAdd()
The advantage to them being overrideable instance methods would be that I could add record level checks to them. For example a user may only be able to delete certain customers so I could put code in my AllowDelete() that would do something like:
if (IsInRole(ROLE_Manager) && this.KeyAccount) return (true && base.AllowDelete()); else return false;
Of course in this case your save/delete code would just call the instance's AllowDelete() before doing a delete and throw a SecurityException (or whatever).
Hope this helps. Love to hear others comments on this.
Personally, I really want to get rid of any UI oriented stuff in the entities. I have to add some code to fit into the MS databinding framework, but that is also not what I'd like to see. An 'AllowAdd' method is UI code, and has no meaning in a BL tier or other code the entity is used in.
Joined: 29-Jul-2005
Otis wrote:
However, how can this not be solved with a validation object ?
Well, I guess it could, I just don't want to write it. My main point here is that these are common security patterns which code generation should make alot easier to solve.
Otis wrote:
I was thinking of adding tap in code for this. As the concept of a 'user' is unclear, undefined and not in the scope of llblgen pro code: is it a windows user, a user of your own role system, an asp.net user / role ? etc.
In this context I meant user as in the user of your tool/API, in other words the developer.
Otis wrote:
Role required to instantiate entity: ${EntityName}Read Role required to add new entity: ${EntityName}New Role required to edit entity: ${EntityName}Edit Role required to delete entity: ${EntityName}Delete Role required for property: ${EntityName}${PropertyName}Access
What's 'Role' in this context?
Equivilent to an .Net role which could be checked with System.Thread.Threading.CurrentPrinciple.IsInRole(RoleName).
Otis wrote:
Personally, I really want to get rid of any UI oriented stuff in the entities. I have to add some code to fit into the MS databinding framework, but that is also not what I'd like to see. An 'AllowAdd' method is UI code, and has no meaning in a BL tier or other code the entity is used in.
I totally disagree. The (encapsulated) business object's responsiblity is to provide me information about it's state in the current context. I see AllowAdd() as very much the same as IsValid(). Only the business object knows if it is valid. It has to expose this in it's API to allow the UI layer to know whether the biaobj is valid and how to deal with it. In the same way only the business object knows if a user can add a record or access a property. Where else would you put this code? Not in the UI for sure!
I look at it this way when trying to detemine whay layer something should reside. If I am writting a Windows UI and a Web UI against the same Business layer... would I have to duplicate code in each UI to perform the same thing?
If AllowAdd() for example is to be implemented in the UI layer then I am writting the SAME code twice.
If CurrentUser.IsInRole("ADD_CUSTOMER")
BLAH BLAH
This is very much (as you said, all security is) a business rule. Let's say I have the above code in the UI of my Win and Web app. Now, my business analyst says... oh, a user (end user) can (be able to) only add a customer record if they are the account manger for that customer's company, or the system administrator. This is business rule code that should be in the business layer... So, now in the UI layers I have something like:
If Customer.AllowAdd()
BLAH BLAH
Now, if the business rule changes I modify the Customer bizobj's AllowAdd method, build the DLL and ship it. No need to change the Web or Win UI. So it is certinaly NOT a UI responsiblity.
Yes, I could write this business rule in the bizobj without exposing it to the UI through the bizobj's api... but how then do you propose to expose this information to the UI? So, if by a UI method you mean it will mostly be called by the UI, you are correct. But it has to be surfaced somehow, doesn't it?
BOb
Joined: 17-Aug-2003
PilotBob wrote:
Otis wrote:
However, how can this not be solved with a validation object ?
Well, I guess it could, I just don't want to write it. My main point here is that these are common security patterns which code generation should make alot easier to solve.
Sure, but that's also applicable for a lot of other problems. The thing is: is it part of our scope to provide these templates. I'm not convinced, also because it is hard to make it usable for everybody, as a lot of people want to design their applications differently.
Otis wrote:
I was thinking of adding tap in code for this. As the concept of a 'user' is unclear, undefined and not in the scope of llblgen pro code: is it a windows user, a user of your own role system, an asp.net user / role ? etc.
In this context I meant user as in the user of your tool/API, in other words the developer.
Ah, see here we already go different routes. In no situation am I talking about a developer. I'm talking about the user of the end result, thus the end-user who wants to execute an action and the code doesn't proceed because a security check fails.
You want code being added so a developer can be blocked from using certain pieces of code? How is that enforceable?
Otis wrote:
Role required to instantiate entity: ${EntityName}Read Role required to add new entity: ${EntityName}New Role required to edit entity: ${EntityName}Edit Role required to delete entity: ${EntityName}Delete Role required for property: ${EntityName}${PropertyName}Access
What's 'Role' in this context?
Equivilent to an .Net role which could be checked with System.Thread.Threading.CurrentPrinciple.IsInRole(RoleName).
THough others might want to use their own user/role system as they use that in their own system running on a big iron box in the basement.
Otis wrote:
Personally, I really want to get rid of any UI oriented stuff in the entities. I have to add some code to fit into the MS databinding framework, but that is also not what I'd like to see. An 'AllowAdd' method is UI code, and has no meaning in a BL tier or other code the entity is used in.
I totally disagree. The (encapsulated) business object's responsiblity is to provide me information about it's state in the current context. I see AllowAdd() as very much the same as IsValid(). Only the business object knows if it is valid. It has to expose this in it's API to allow the UI layer to know whether the biaobj is valid and how to deal with it. In the same way only the business object knows if a user can add a record or access a property. Where else would you put this code? Not in the UI for sure!
What if you use a model-view-controller approach? then you would want to have AllowAdd NOT on the entity, but in the controller. What if AllowAdd is context sensitive in such a way that you need a pluggable approach, similar to validators? IMHO that ends up with a validator that is named differently.
I look at it this way when trying to detemine whay layer something should reside. If I am writting a Windows UI and a Web UI against the same Business layer... would I have to duplicate code in each UI to perform the same thing?
If AllowAdd() for example is to be implemented in the UI layer then I am writting the SAME code twice.
If CurrentUser.IsInRole("ADD_CUSTOMER") BLAH BLAH
This is very much (as you said, all security is) a business rule. Let's say I have the above code in the UI of my Win and Web app. Now, my business analyst says... oh, a user (end user) can (be able to) only add a customer record if they are the account manger for that customer's company, or the system administrator. This is business rule code that should be in the business layer... So, now in the UI layers I have something like:
If Customer.AllowAdd() BLAH BLAH
Now, if the business rule changes I modify the Customer bizobj's AllowAdd method, build the DLL and ship it. No need to change the Web or Win UI. So it is certinaly NOT a UI responsiblity.
It's a controller's responsibility, in the context you described (IMHO). Because you also could have: if(SecurityManager.AllowAdd(customer)) { //.. }
As you have t make a call anyway, so the weak spot is the necessity of WRITING the call, how the call looks like isn't important.
What I understood and still think is what people are after is: set and forget code. I.o.w.: code which simply guards what can be done and what not without writing the CALL. This thus comes down to for example a beforesave validation. If the user calling isn't allowed to save that entity, the current process should stop, so an exception should be thrown. That's set and forget code: you don't have to write the call statement, so you also don't run the risk of forgetting to write the call statement.
Same with auditing. Auditing is important, it's requested / discussed often in Architecture, and I have the feeling it's not straight forward. It's the same kind of code: you can do it in two ways: - manually, like this forum system does (I didn't go through the hassle of adding set-and-forget auditing logic to the system, it audits when an action has been completed) - through code which is placed automatically in a process call-chain. So you then only have to write the audit code once, and some configuration routine perhaps (like CreateValidator in an entity) and it's done: it's always called, and you don't run the risk of forgetting to add the call to the audit routine.
If I look at a routine like 'AllowAdd()', I don't really understand what that routine will do internally. The thing is that I haven't specified in which context I want the routine to check if the entity is addable. Do I want it to check if addition/insert is ALWAYS blocked, or just in this particular case?
Is it used to be the SINGLE piece of logic in the app which controls what should be done and what not, or is it guard logic, i.e. code which is there if a bug in the UI code allows a user to execute a given task. ?
Yes, I could write this business rule in the bizobj without exposing it to the UI through the bizobj's api... but how then do you propose to expose this information to the UI? So, if by a UI method you mean it will mostly be called by the UI, you are correct. But it has to be surfaced somehow, doesn't it?
Yes, though I'd like to have that kind of code in a piece of UI support code, which is consulted by the UI and which thus doesn't force the developer to add all kinds of code which is solely used by the UI to the entity. Let's not debate over if that's OK or not, there are multiple ways to design a system, and one group will say: put it in the entity!, and another group (let's say they're equal in size ) will say: "no! place that code outside the entity!".