471,348 Members | 1,555 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,348 software developers and data experts.

Implement authorization in win forms

Whats the best way of implementing authorization in a win forms
application.
I mean things like show/hide or enable/disable Save button ,creating
context menus etc.
Apr 10 '08 #1
13 7253
If you get stuck, please let me know. This is part of
System.ComponentModel, an area that I know very well. Although I
understand them, I haven't personally *created* an extension property
before, but I imagine that it isn't too tricky *if* you understand how
the rest of that area works. Actually, I'd happily use it as an excuse
to do some more digging in that area... ;-p

Marc
Apr 10 '08 #2
On Apr 11, 4:25 am, Marc Gravell <marc.grav...@gmail.comwrote:
For info, here is a rough sketch of what the component would look
like... this allows both IDE and programmatic usage; note that for
roles-based security you'd also need to initialize the principal - at
the most primative this can be as simple as:

Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("Marc"), // name of user
new string[] { "BASIC" } // array of roles that the
user has
);

Obviously if your security model is more complex, you may need to
change things ;-p

[ProvideProperty("Role", typeof(Control))]
[ToolboxItemFilter("System.Windows.Forms")]
[Description("Provides automatic role-checking")]
public class RoleDisabler : Component, IExtenderProvider
{
private Dictionary<Control, stringmap
= new Dictionary<Control, string>();
[DefaultValue("")]
public string GetRole(Control control)
{
if (control == null) return "";
string role;
map.TryGetValue(control, out role);
return role ?? "";
}
public void SetRole(Control control, string role)
{
if (control == null) return;
bool add = false, remove = false;
if (string.IsNullOrEmpty(role))
{
remove = map.Remove(control);
}
else
{
add = !map.ContainsKey(control);
map[control] = role;
}
if (!DesignMode)
{
SetEnabled(control);
if (add)
{
control.ParentChanged += control_ParentChanged;

}
else if (remove)
{
control.ParentChanged -= control_ParentChanged;
}
}
}
private void SetEnabled(Control control)
{
if (DesignMode || control == null) return;
string role;
if (map.TryGetValue(control, out role))
{
IPrincipal principal = Thread.CurrentPrincipal;
control.Enabled = principal == null ? false :
principal.IsInRole(role);
}
}
void control_ParentChanged(object sender, EventArgs e)
{
SetEnabled(sender as Control);
}
bool IExtenderProvider.CanExtend(object obj)
{
return obj is Control;
}
}
Thanks..

How will i use the RoleDisabler ? would i drag it from the toolbar
like tooltip?
Jun 27 '08 #3
On Apr 11, 1:49 pm, parez <psaw...@gmail.comwrote:
On Apr 11, 4:25 am, Marc Gravell <marc.grav...@gmail.comwrote:
For info, here is a rough sketch of what the component would look
like... this allows both IDE and programmatic usage; note that for
roles-based security you'd also need to initialize the principal - at
the most primative this can be as simple as:
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("Marc"), // name of user
new string[] { "BASIC" } // array of roles that the
user has
);
Obviously if your security model is more complex, you may need to
change things ;-p
[ProvideProperty("Role", typeof(Control))]
[ToolboxItemFilter("System.Windows.Forms")]
[Description("Provides automatic role-checking")]
public class RoleDisabler : Component, IExtenderProvider
{
private Dictionary<Control, stringmap
= new Dictionary<Control, string>();
[DefaultValue("")]
public string GetRole(Control control)
{
if (control == null) return "";
string role;
map.TryGetValue(control, out role);
return role ?? "";
}
public void SetRole(Control control, string role)
{
if (control == null) return;
bool add = false, remove = false;
if (string.IsNullOrEmpty(role))
{
remove = map.Remove(control);
}
else
{
add = !map.ContainsKey(control);
map[control] = role;
}
if (!DesignMode)
{
SetEnabled(control);
if (add)
{
control.ParentChanged += control_ParentChanged;
}
else if (remove)
{
control.ParentChanged -= control_ParentChanged;
}
}
}
private void SetEnabled(Control control)
{
if (DesignMode || control == null) return;
string role;
if (map.TryGetValue(control, out role))
{
IPrincipal principal = Thread.CurrentPrincipal;
control.Enabled = principal == null ? false :
principal.IsInRole(role);
}
}
void control_ParentChanged(object sender, EventArgs e)
{
SetEnabled(sender as Control);
}
bool IExtenderProvider.CanExtend(object obj)
{
return obj is Control;
}
}

Thanks..

How will i use the RoleDisabler ? would i drag it from the toolbar
like tooltip?
That was great.. thanks...
I have a question..
When will the SetEnabled function execute?
Jun 27 '08 #4
On Apr 11, 2:14 pm, parez <psaw...@gmail.comwrote:
On Apr 11, 1:49 pm, parez <psaw...@gmail.comwrote:
On Apr 11, 4:25 am, Marc Gravell <marc.grav...@gmail.comwrote:
For info, here is a rough sketch of what the component would look
like... this allows both IDE and programmatic usage; note that for
roles-based security you'd also need to initialize the principal - at
the most primative this can be as simple as:
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity("Marc"), // name of user
new string[] { "BASIC" } // array of roles that the
user has
);
Obviously if your security model is more complex, you may need to
change things ;-p
[ProvideProperty("Role", typeof(Control))]
[ToolboxItemFilter("System.Windows.Forms")]
[Description("Provides automatic role-checking")]
public class RoleDisabler : Component, IExtenderProvider
{
private Dictionary<Control, stringmap
= new Dictionary<Control, string>();
[DefaultValue("")]
public string GetRole(Control control)
{
if (control == null) return "";
string role;
map.TryGetValue(control, out role);
return role ?? "";
}
public void SetRole(Control control, string role)
{
if (control == null) return;
bool add = false, remove = false;
if (string.IsNullOrEmpty(role))
{
remove = map.Remove(control);
}
else
{
add = !map.ContainsKey(control);
map[control] = role;
}
if (!DesignMode)
{
SetEnabled(control);
if (add)
{
control.ParentChanged += control_ParentChanged;
}
else if (remove)
{
control.ParentChanged -= control_ParentChanged;
}
}
}
private void SetEnabled(Control control)
{
if (DesignMode || control == null) return;
string role;
if (map.TryGetValue(control, out role))
{
IPrincipal principal = Thread.CurrentPrincipal;
control.Enabled = principal == null ? false :
principal.IsInRole(role);
}
}
void control_ParentChanged(object sender, EventArgs e)
{
SetEnabled(sender as Control);
}
bool IExtenderProvider.CanExtend(object obj)
{
return obj is Control;
}
}
Thanks..
How will i use the RoleDisabler ? would i drag it from the toolbar
like tooltip?

That was great.. thanks...
I have a question..
When will the SetEnabled function execute?
I think i got it. thanks..once again..you were a life saver..
Jun 27 '08 #5
When will *the SetEnabled function execute?

When not in the designer (DesignMode), it executes when you either
change the role (SetRole), or when the control is added to a parent.
The reason for this second bit is this is always the last thing that
designer-generated code does - so it will take precendence over the
designer.
I think i got it. thanks..once again..you were a life saver..- Hide quotedtext -
No problem; I'm always up for an excuse to mess in the
System.ComponentModel ;-p

Marc
Jun 27 '08 #6
Basically I need function RoleLevel( role, department) which returns access
level.
The inbuilt roles-based security (IPrincipal) only covers single-
dimension roles. You can of course shim this by using roles like
SOMEDEPT_EDIT, SOMEDEPT_READ etc; whether that is sensible or not
depends on the scenario. Another option is NT ACLs, but then you need
to impersonate into that NT user - but it can be very flexible.

Marc
Jun 27 '08 #7
On Apr 11, 5:06 pm, Marc Gravell <marc.grav...@gmail.comwrote:
When will the SetEnabled function execute?

When not in the designer (DesignMode), it executes when you either
change the role (SetRole), or when the control is added to a parent.
The reason for this second bit is this is always the last thing that
designer-generated code does - so it will take precendence over the
designer.
I think i got it. thanks..once again..you were a life saver..- Hide quoted text -

No problem; I'm always up for an excuse to mess in the
System.ComponentModel ;-p

Marc
Hi,

I just one more issue... If a control has sub-control(component) then
it does not show up for the sub components.
e.g MenuStrip control has ToolStripMenuItem children. How do I make
it show up(in properties) for those controls.

TIA
Jun 27 '08 #8
I just one more issue... If a control has sub-control(component) then
it does not show up for the sub components.
e.g MenuStrip control has ToolStripMenuItem children. *How do I make
it show up(in properties) for those controls.
I suspect that is because ToolStripMenuItem isn't a Control, and I
restricted it to Controls; Changed as below (I also removed the events
stuff - didn't seem necessary in hindsight):

[ProvideProperty("Role", typeof(Control))]
[ToolboxItemFilter("System.Windows.Forms")]
[Description("Provides automatic role-checking")]
public class RoleDisabler : Component, IExtenderProvider
{
private Dictionary<object, stringmap
= new Dictionary<object, string>();
[DefaultValue("")]
public string GetRole(object obj)
{
if (obj == null) return "";
string role;
map.TryGetValue(obj, out role);
return role ?? "";
}
public void SetRole(object obj, string role)
{
if (obj == null) return;
if (string.IsNullOrEmpty(role))
{
map.Remove(obj);
}
else
{
map[obj] = role;
}
if (!DesignMode)
{
SetEnabled(obj);
}
}
private void SetEnabled(object obj)
{
if (DesignMode || obj == null) return;
string role;
if (map.TryGetValue(obj, out role))
{
IPrincipal principal = Thread.CurrentPrincipal;
bool isInRole = principal == null ? false :
principal.IsInRole(role);
if (obj is Control)
{
((Control)obj).Enabled = isInRole;
}
else if (obj is ToolStripItem)
{
((ToolStripItem)obj).Enabled = isInRole;
}
}
}
bool IExtenderProvider.CanExtend(object obj)
{
return obj is Control || obj is ToolStripItem;
}
}
Jun 27 '08 #9
On Apr 14, 4:01 pm, Marc Gravell <marc.grav...@gmail.comwrote:
I just one more issue... If a control has sub-control(component) then
it does not show up for the sub components.
e.g MenuStrip control has ToolStripMenuItem children. How do I make
it show up(in properties) for those controls.

I suspect that is because ToolStripMenuItem isn't a Control, and I
restricted it to Controls; Changed as below (I also removed the events
stuff - didn't seem necessary in hindsight):

[ProvideProperty("Role", typeof(Control))]
[ToolboxItemFilter("System.Windows.Forms")]
[Description("Provides automatic role-checking")]
public class RoleDisabler : Component, IExtenderProvider
{
private Dictionary<object, stringmap
= new Dictionary<object, string>();
[DefaultValue("")]
public string GetRole(object obj)
{
if (obj == null) return "";
string role;
map.TryGetValue(obj, out role);
return role ?? "";
}
public void SetRole(object obj, string role)
{
if (obj == null) return;
if (string.IsNullOrEmpty(role))
{
map.Remove(obj);
}
else
{
map[obj] = role;
}
if (!DesignMode)
{
SetEnabled(obj);
}
}
private void SetEnabled(object obj)
{
if (DesignMode || obj == null) return;
string role;
if (map.TryGetValue(obj, out role))
{
IPrincipal principal = Thread.CurrentPrincipal;
bool isInRole = principal == null ? false :
principal.IsInRole(role);
if (obj is Control)
{
((Control)obj).Enabled = isInRole;
}
else if (obj is ToolStripItem)
{
((ToolStripItem)obj).Enabled = isInRole;
}
}
}
bool IExtenderProvider.CanExtend(object obj)
{
return obj is Control || obj is ToolStripItem;
}

}
I tried that .. It did not work... it still doesnt show it..
Jun 27 '08 #10
Curoious - even though it accepts multiple ProvidePropertyAttribute
declarations, only the first is used... never mind; change the
[ProvideProperty] line to:

[ProvideProperty("Role", typeof(Component))]

Marc
Jun 27 '08 #11
On Apr 10, 10:49*pm, parez <psaw...@gmail.comwrote:
Whats the best way of implementingauthorizationin a win forms
application.
I mean things like *show/hide or enable/disable Save button ,creating
context menus *etc.
Hi,

Visual Guard .Net is probably a good solution:

http://www.visual-guard.com/EN/.net-...ion-tool#admin
Jun 27 '08 #12
On Apr 14, 4:01 pm, Marc Gravell <marc.grav...@gmail.comwrote:
I just one more issue... If a control has sub-control(component) then
it does not show up for the sub components.
e.g MenuStrip control has ToolStripMenuItem children. How do I make
it show up(in properties) for those controls.

I suspect that is because ToolStripMenuItem isn't a Control, and I
restricted it to Controls; Changed as below (I also removed the events
stuff - didn't seem necessary in hindsight):

[ProvideProperty("Role", typeof(Control))]
[ToolboxItemFilter("System.Windows.Forms")]
[Description("Provides automatic role-checking")]
public class RoleDisabler : Component, IExtenderProvider
{
private Dictionary<object, stringmap
= new Dictionary<object, string>();
[DefaultValue("")]
public string GetRole(object obj)
{
if (obj == null) return "";
string role;
map.TryGetValue(obj, out role);
return role ?? "";
}
public void SetRole(object obj, string role)
{
if (obj == null) return;
if (string.IsNullOrEmpty(role))
{
map.Remove(obj);
}
else
{
map[obj] = role;
}
if (!DesignMode)
{
SetEnabled(obj);
}
}
private void SetEnabled(object obj)
{
if (DesignMode || obj == null) return;
string role;
if (map.TryGetValue(obj, out role))
{
IPrincipal principal = Thread.CurrentPrincipal;
bool isInRole = principal == null ? false :
principal.IsInRole(role);
if (obj is Control)
{
((Control)obj).Enabled = isInRole;
}
else if (obj is ToolStripItem)
{
((ToolStripItem)obj).Enabled = isInRole;
}
}
}
bool IExtenderProvider.CanExtend(object obj)
{
return obj is Control || obj is ToolStripItem;
}

}
Hi Marc,

I added the following to the RoleDisabler .. and now it also enables /
disables everytime my permission changes..
Thanks again..

private void HookUpEventhandlers()
{

UserAccessInfo.UserPermissionsUpdated += new
EventHandler<EventArgs>(UserAccessInfo_UserPermiss ionsUpdated);
}

void UserAccessInfo_UserPermissionsUpdated(object sender,
EventArgs e)
{
foreach (object obj in map.Keys)
{
try
{
SetEnabled(obj);
}
catch(Exception ex)
{

Trace.WriteLineIf(Logger.Instance.TraceSwitch.Trac eError,
ExceptionUtility.GetInnerMostException(ex).Message );
}
}
}
Jun 27 '08 #13
Hi Marc

Firstly thanks for posting your code - it's proving very useful for me (and many others I'm sure).

I've tested the code on my forms and it seems to deal very well with most things but "falls down" a little with things like datagridviews etc where more than one property would be bound - the code you've posted can happily enable/disable the entire control (i.e. all cols) but how would you go about hiding/making readonly some columns dependent on roles (i.e. "CanView"/"CanEdit" type properties?

Thanks in advance
Martin
Jul 16 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Ronald S. Cook | last post: by
4 posts views Thread by Mark Olbert | last post: by
3 posts views Thread by nick | last post: by
4 posts views Thread by Johnnie Norsworthy | last post: by
2 posts views Thread by Water Cooler v2 | last post: by
1 post views Thread by sonu | last post: by
1 post views Thread by Anthony Small | last post: by
reply views Thread by yofnik | last post: by
4 posts views Thread by xke | last post: by
reply views Thread by Ronak mishra | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.