Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authorization of UI Elements in .NET WinForms

I have a general question about the best approach for authorizing UI elements for application Roles. What I mean is an Administrator can see buttons, menu items, etc, that a regular User cannot see. What is the best practice for this?

I realize that there could be multiple screens based on Role (an Admin screen, the same screen duplicated for User, etc), that definitely seems like overkill. I also want to keep Separation of Concern so my authorization code is not intermingled with display functionality. In other words, I want to avoid:

if( current_user.IsInRole("administrator") )
  button.Enabled = true;

I have been looking at Aspects with PostSharp, which seems almost exactly what I want to do, but it doesn't seem to logically extend to the UI.

I'm sure I'm missing something, what is it?

Thanks -

like image 214
grefly Avatar asked Dec 16 '10 13:12

grefly


1 Answers

It seems likely that your code will eventually compile a list of UI elements to hide, or perform a given action to, and then perform those actions based on the current role. Something like

Dictionary<Control, Action<Control, string>> actions = new Dictionary<Control, Action<Control, string>>
{
    { button, (c, r) => c.Enabled = (r == "administrator") },
    // etc.
};

How you compile that list is primarily what your question is concerned with. AOP frameworks definitely help with the separation of concerns, but a homebrew solution wouldn't be impossible. I'm thinking something like:

  • Create an EnableForRoleAttribute, with parameter role.
  • Reflect on your forms (possibly using reflection to find the forms, or possibly providing them to your code directly, or even finding forms decorated with a RoleVaryingAttribute of your creation).
  • Reflect on the fields of your forms, filtering for Control instances, then for Control instances with the EnableForRoleAttribute.
  • Now you have your list! Set Enabled based on the role.

The above bulleted list is specific to your Enabled example, mainly because attributes can't take lambdas as parameters :(. You could be more flexible with a SetPropertyIfInRoleAttribute with parameters role, propertyName, and propertyValue. Or any such construction.

Basically, the AOP frameworks make this work easier for you, and some like PostSharp make it happen at compilation time instead of runtime. But the homebrew solution is pretty valid too.

like image 121
Domenic Avatar answered Sep 22 '22 13:09

Domenic