- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Role based access...
Joined: 05-Aug-2005
Hello,
In our app we provide a .Net role (we call it a permission) for each entity task. So, generally 4 per entity:
App.Customer (View) App.Customer.Add App.Customer.Edit App.Customer.Delete
Is there any place to plug these roles in at the entity level?
If not, any thoughts to adding this an an ER?
The idea would be that I could specify the permissions in the UI for each Add / Edit / Delete (not sure where View would plug into the BL (Perhaps at the class level), that is basically used on our menu.)
Then the generator could add permission demand attributes to the methods in Self-service and the adapter could perhaps have Allow????? properties/methods on each Entity that the adapter calls. If the Allow returns false a SecurityException() should be raised.
The main exception is that Save should be allowed if the user has the Add permission but not the edit permission if the entity is a new entity.
Or, perhaps there is already consideration for this in the current version? I was thinking I may be able to add the Allow????? methods to my templates somehow.
In addition the UI layer could do something like:
btnSave.Visible = MyEntity.AllowEdit() && Mode == PageMode.Add;
?????
BOb
The save stuff can be done using an IEntityValidator implementation. You can set the instance for this for an entity in an include template bound to the templateid for custom entity initialization, which is Custom_EntityInitializationTemplate. (see 'Adding your own code to the generated classes'). If the user isn't allowed to perform an action, Validate(), which calles into the entity validator, should thrown an entity validation exception, and the save will then be aborted.
Your methods to check, Allow??? can be added to an entity through an include template bound to the template id Custom_EntityAdapterTemplate, if you're using adapter and Custom_EntityUsingEntityBaseTemplate if you're using 2-class scenario selfservicing.
The code in your include template is then added at the bottom in a region. Use template logic to control which code is added to which entity.
To intercept field changes, override OnFieldValidate in an entity. In there you can check if a field has to be set or not due to security restrictions. If not, throw an exception, if it's allowed simply do nothing. Entities also have validation objects for fields, but these classes don't have a reference back to the entity they're contained in, so you can't grab the actual role and check, these validator objects are meant for pure hardcoded rule checks, like id > 0.
With permission demand attributes you're referring to .NET attributes which demand the owner of the appdomain which calls the method to be in a given windows security role ?
Joined: 05-Aug-2005
Otis wrote:
With permission demand attributes you're referring to .NET attributes which demand the owner of the appdomain which calls the method to be in a given windows security role ?
Yes, .Net attributes. It has nothing to do with the owner of the domain. If has to do with the IPrincipal object of the current thread. It doesn't matter if the concrete class is a windows principal or a forms auth principal. The concept is the same.
using System.Security.Permissions;
[PrincipalPermissionAttribute(SecurityAction.Demand, Role = Rights.FAAPVendorsAdd)]
The attribute can go on a class or method or actually property I think.
BOb
pilotboba wrote:
Otis wrote:
With permission demand attributes you're referring to .NET attributes which demand the owner of the appdomain which calls the method to be in a given windows security role ?
Yes, .Net attributes. It has nothing to do with the owner of the domain. If has to do with the IPrincipal object of the current thread. It doesn't matter if the concrete class is a windows principal or a forms auth principal. The concept is the same.
using System.Security.Permissions; [PrincipalPermissionAttribute(SecurityAction.Demand, Role = Rights.FAAPVendorsAdd)]
The attribute can go on a class or method or actually property I think.
Interesting.
As these are required on a lot of methods/properties, it's a bit of a problem though: per method/property you should be able to specify which role(s) have which rights. I mean a problem with the setup of having your code generated, which means that the generated code has to embed the attributes required.
What I was wondering was: is it an idea to apply the attributes on the BL code and use adapter? I mean: the BL code's caller is calling the BL to perform an action (like 'save this new order (and pass in an order with order row graph)') and that action can't start if the caller doesn't have the right principal. Because adapter entities don't contain any persistence logic, the caller can't do things without the BL anyway.
But perhaps I'm not understanding your system's setup in full. Your idea is interesting, the only drawback I see is that to utilize it with code generation, it requires a lot of work (potentially).
Joined: 05-Aug-2005
Otis wrote:
As these are required on a lot of methods/properties
Well, we don't do propertly level roles. We just do Entity level. So generally there are 4.
The View permission is an attribute of the class. Our UI forces that view permissions to be enabled if any of the Add/Edit/Delete permissions are assigned.
The Delete permission is an attribute of the Delete method.
The Add/Edit depend on the implementation of the object. But, say you have a save method that delegates to an Update() method and an Add() method. The Edit permission would attribute the update method and the add attribute, well duh the Add method.
The above would seem to work with self-servicing, not sure about adapter.
Otis wrote:
, it's a bit of a problem though: per method/property you should be able to specify which role(s) have which rights. I mean a problem with the setup of having your code generated, which means that the generated code has to embed the attributes required.
Exactally, that's what I am looking for...
-
The generator to attribute the methods which would mean the UI has to have a place to specify the role names.
-
The generator would create 3 methods AllowAdd(), AllowEdit(), AllowDelete() which would return a bool. The code is simple. Actually, the code could be in the base class and the role names could be stored in 3 private fields in the concrete class. The code would be something like:
Public bool AllowAdd() {
return System.Threading.Thread.CurrentPrincipal.IsInRole(_addRole);
}
Otis wrote:
What I was wondering was: is it an idea to apply the attributes on the BL code and use adapter?
Yes... I assume when you say BL you mean another layer [service layer] in the app that is what is exposed to the UI and contains all the query, business rules and such code. (Basically using the LLBLGEN Entities as data objects?) Of course, each BL class will have a Save (which delegates to Update/New methods) and Delete method. Yes, that is an option. Of course it would all classes would have to be hand coded.
Otis wrote:
But perhaps I'm not understanding your system's setup in full. Your idea is interesting, the only drawback I see is that to utilize it with code generation, it requires a lot of work (potentially).
I think you have the general idea. I still havn't decided on using Self-servicing or Adapter.
With self-servicing my thought is that the generated code would be the BL layer. So, the security attributes/checking would have to be encapsulated into the Entity classes.
However, with adapter the thought is to build a seperate BL layer that passes/accepts entity objects. This seems more like a manager pattern where the rules are not actually encapsulated in the entitys. This is actually simmilar to our current version that uses typed data sets an business rules classes which contain most of the business code.
Comments and feedback are welcome.
BOb
Joined: 05-Aug-2005
Otis wrote:
But perhaps I'm not understanding your system's setup in full. Your idea is interesting, the only drawback I see is that to utilize it with code generation, it requires a lot of work (potentially).
Is support for role based security something that you are considering for 2.0, or should I plan to write my own template to do this?
Only problem with writting templates is where would I store the role names. I guess I could store them as extended properties of the table in the database?
BOb
pilotboba wrote:
Otis wrote:
But perhaps I'm not understanding your system's setup in full. Your idea is interesting, the only drawback I see is that to utilize it with code generation, it requires a lot of work (potentially).
Is support for role based security something that you are considering for 2.0, or should I plan to write my own template to do this?
for 2.0 this isn't considered in the first release of 2.0. What we will add is a lot more ways to flexibly extend the code, either by overriding methods, including templates etc. The main issue is that your request is specific but at the same time also very intrusive when it comes to modifying the code through code generation: it's not easily solved by using include templates for example, every public method has to be decorated.
Only problem with writting templates is where would I store the role names. I guess I could store them as extended properties of the table in the database?
That's an option, though what do you want to do about the methods exposed by the runtime library?