1.53 BO Field level security

1.53 BO Field level security

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


esteban404 posted on Wednesday, June 28, 2006

My wonderful <teeth grinding>users</teeth grinding> want me to use Role-based security for field updates. So if a BO needs tooling information, only someone in the Tool, Tool Manager or Project Manager can change that field. The field setter is the only place I can think of to enforce such a requirement, but it's not a bindable property on the object.

I'm looking into Rocky's control extension idea from a previous post for some control appearance requirements, but it doesn't seem applicable to this problem. This seems a hack, but how about using use a logical block to determine membership and turn off fields (make the form's fields read only)?

For example in the WinForm UI's DataBind() method:
if(!(user.IsInRole("Tool") || user.IsInRole("Tool Manager") || user.IsInRole("Administrator"))
txtToolNumber.Properties.ReadOnly = true;

This form is used by a team of people with many roles possible. I'd have to see if that truly does not allow edititing, but it seems verbose enough to be valid. [:-)] The suits say we need to be able to show the person filling in these fields is qualified to enter the value. To that end I log the history info, my goal is to disallow entry if you're not is an allowed role.

Has anyone a better suggestion than this if block junk? The archives are mostly about securing an object, not specific fields within the object, so I have not found much.

_E

esteban404 replied on Wednesday, June 28, 2006

Is it bad to add a CanEditTool bit and property to the BO? I would start with the form's controls all set to ReadOnly and change it to false if the user is in the appropriate role. So far about 60% of the fields in the BO need this to be available in this project. I'd then bind the form to the bit in the DataBind() method. I've read the previous posts, seems to be the thought.

_E

ajj3085 replied on Wednesday, June 28, 2006

You can go that route, but the problem is you end up with a bunch of extra properties, which really are there just to support databinding.

Why doesn't the extender control work for what you need (I have to admin I'm not very familar with it)?

Andy

esteban404 replied on Wednesday, June 28, 2006

>Why doesn't the extender control work for what you need (I have to admin I'm not very familar with it)?

The way I understand it is an attibute is applied to a class which inherits the control type you want to extend and lists the property and type (of control) you are extending. But I don't know what/how to implement a security level value in this context. I mean, I create this and how do I define what roles are required in the extended control's code for binding to work out of the box? It's a brain problem. I just can't find such an example for an object such as mine.

And I assume that this class modification is in the UI layer since it's a control.

I'll contact the vendor of the control set we use and see if they have an example. It sounds like a marvelous and preferred way to do it *if* I knew how.

I'd apprciate any links to something. I'm still searching all the .NET places. No luck other than the famous "just implement it as an extended control." Yea, uh, I get that, thanks.  :-\

_E

Brian Criswell replied on Wednesday, June 28, 2006

I do not know if it would help you, but I back-ported the authorization rules and read/write authorization control to CSLA 1.53.  http://forums.lhotka.net/forums/permalink/2364/2392/ShowThread.aspx#2392

esteban404 replied on Wednesday, June 28, 2006

Thanks, Brian. I haven't seen the implementation in the new version so I was clueless to the fact that what was being discussed was not what I was thinking.

I'll have to get an excuse to buy the book so I can understand how it works. It'd be for my personal collection since I'm not suppose to code any .NET 2.0 apps at work. That doesn't mean I can't justify it for my pro-bono work. <heh heh>

_E

RockfordLhotka replied on Wednesday, June 28, 2006

Like all business rules, authorization rules belong in the business layer, not in the UI. So putting role names into the UI in any form is (I think) a bad idea. That is implementing business logic in the UI, where it is the least maintainable and most expensive.

What CSLA 2.0 does, is provide a formalized way by which you can put authorization logic into the business object, and then have the UI react to that logic to alter the user's experience. The UI doesn't know why it alters the appearance, it just knows how. Seperation of concerns.

esteban404 replied on Sunday, July 02, 2006

I did order the C# 2005 BO book, so I'm looking forward to understanding the model better. Unfortunately, some rules get bent and broken when working in an environment where no excuse is satisfactory to justify doing things correctly and taking the 2 days to code and test it. I'm going to leave it open for corrections to a better/simpler model at a later time.

It bites, but there little to do about it.

_E

JHurrell replied on Thursday, June 29, 2006

I have to do this as well and although it does add a lot of properties, I've gone down the route where I create UserCanRead[Property] and UserCanWrite[Property] properties for all the properties in my BOs.

For example, if I have a user object with the property FirstName, I would also have UserCanReadFirstName and UserCanWriteFirstName. Since I use CodeSmith to do this, it's not much trouble for me.

By default, they all return true, except of course for the PK properties. If a specific user cannot read or write a property, it's very easy to edit the UserCanRead and UserCanWrite to restrict access. This also comes in handy if the accessibility of a property is contingent upon the state of another property.

In the property get/set, I call the appropriate UserCanRead and UserCanWrite and throw an exception if the user isn't authorized to get or set.

Using my method, it's easy to then bind the UserCanReads and UserCanWrites to the Enabled, ReadOnly or Visible states of controls.

It works like a charm, it's very simple to use and easy to understand. Of course, I'm always open to improvements. If there's another way, I'd love to hear it.

- John


JHurrell replied on Thursday, June 29, 2006

Just for kicks, I've attached a sample object using the UserCanRead and UserCanWrite pattern I've described previously.

It also shows how I use PropertyIsBroken properties to determine if a specific property is broken. I can bind to the PropertyIsBroken properties and set the visible state of "*" labels or error messages.

- John

esteban404 replied on Sunday, July 02, 2006

Thanks, John. I think that will help me keep the hack reasonable. I'll probably add a bit array to store the settings. I hope to have time to use the converted csla 2.0 authorization rules instead of this hack.

_E

esteban404 replied on Friday, July 07, 2006

Got the 2.0 book last night...

I've read all the threads and grabbed the back ported version of the AuthorizationRules (thank you Brian). In the class, there's a call to CSLA.ApplicationContext.User. I see that this User is of type IPrincipal. I already have a custom principal and identity object in my project,  it seems this needs to be added as a customization to the framework so I can use it.

If this goes well, the control in the UI can be bound to the appropriate access type property. I've got more reading to do, but that seems like the basics.

Am I on the right track? If so, I'll add it to the project's security namespace (with my custom principal and identity) to keep the CSLA framework clean. I just want to make sure I understand. It will be a major improvement over the other options of properties everywhere.

_E

ajj3085 replied on Friday, July 07, 2006

What you can do is move your custom Principal and Identity to the business layer, and inherit PrincipalBase.  What is different about your Principal / Identity objects which you think warrant a modification to the framework?

esteban404 replied on Friday, July 07, 2006

ajj3085:
What you can do is move your custom Principal and Identity to the business layer, and inherit PrincipalBase.

It's in the BL now, but not accessible, so... next

ajj3085:
What is different about your Principal / Identity objects which you think warrant a modification to the framework?

There is a call to ApplicationContext.User which doesn't exist in the framework for CSLA 1.53. It'd have to be added so I'm faced with getting a reference to my custom Principal and Identity which is in my application's security space. I think I could add the ported code to that security space in my application and have it function, but, well, planning and execution don't always cooperate.

I have these principal and identity objects in my custom BusinessBase class which inherits from BusinessBase. I believe this nifty trick came from BruceP. I got it last year in a thread regarding modifying the principal and identity objects to include some more properties.

_E

ajj3085 replied on Friday, July 07, 2006

I'm sorry, you said you got the .Net 2.0 book, I assumed you'd be working with .Net 2.0.

So are you going to be adding the concept of ApplicationContext to 1.53, or just the .User property?  If its the latter, you can just use Thead.CurrentPrincipal and make sure any other threads somehow get this principal as well.

What are you doing with the modified business base and extra properties?  Sounds like it could be useful.

Andy

esteban404 replied on Friday, July 07, 2006

ajj3085:
I'm sorry, you said you got the .Net 2.0 book, I assumed you'd be working with .Net 2.0.

So are you going to be adding the concept of ApplicationContext to 1.53, or just the .User property?  If its the latter, you can just use Thead.CurrentPrincipal and make sure any other threads somehow get this principal as well.

2.0 would be preferred, but we won't be using it for another year or two. Management decision that has nothing to do with productivity. Indifferent [:|] I got the book to better understand the concept of authorization on the properties.

1.53 has an ApplicationContext in the CSLA.Server.DataPortal space. It just doesn't have the User property. I can add it, but it's defined in my project, not in the CSLA base assemblies, so it won't compile. I need to either add it to CSLA in an extension space (which I think I'll do), or it needs to be in my project's security space. In either case, it means a refactor to remove the duplicate code it will create since I have a user property on my custom principal.

ajj3085:
What are you doing with the modified business base and extra properties?  Sounds like it could be useful.


I'm using it in conjunction with some notification mechanisms including floating/dockable panels with transparent backcolors to show stats on the system (number of open items, number of items due, etc.) for each of the modules the user wants to see. All have timers in the UI so I don't have to maintain an open connection.

It also facilitates SMTP mail (notifications) from within the classes. I've added just a few for now, but it's linked into a preferences object (CSLA based) where I'm storing the user's environmental prefs and lets the UI grab settings as needed.

It's a bit of a hack sometimes because I "do it all" from db to UI, but it's working and my coworker likes the code. Another one doesn't, but he's a data adapter-only kind of guy. He even smells like Redmond @low tide.

_E

JHurrell replied on Friday, July 07, 2006

esteban404:

I've read all the threads and grabbed the back ported version of the AuthorizationRules (thank you Brian).



Can you provide the link to the thread(s) and the back ported of the AuthorizationRules class? As much as I love my hack ;), I'd prefer to do things the right way.

- John

esteban404 replied on Friday, July 07, 2006

John,

There's a link in this topic's threads from Brian:
http://forums.lhotka.net/forums/thread/2364.aspx

_E

Copyright (c) Marimer LLC