Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / April 2008

Tip: Looking for answers? Try searching our database.

Creating ToolStripMenu based on user rights

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Andrus - 13 Apr 2008 17:38 GMT
I have .NET 2 WinForms MDI application containing 250 ToolStripMenu items.

I need to make some submenus invisible and individual menus invisible if
user has no rights or insuficient level of access. This can be determined at
menu creation time.
Possibilites:

1. Modify WinForms designer generated code manually by not creating
unwanted items. After that it is no more possible to use designer anymore
so this is difficult.

2. Use form OnLoad to remove unwanted items:

protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
if (!SecurityManager.IsAllowed("Invoice") &&
               !SecurityManager.IsAllowed("Order")) {
 FileMenuStrip.DropDownItems.RemoveByKey("UnWantedMenu");
 }

This requires writing a lot of code and hardcoding all menu item names

3. Store access levels in Tag property in designer:
  Tag = @"!SecurityManager.IsAllowed(""Invoice"") &&
!SecurityManager.IsAllowed(""Order"")";
In OnLoad event use reflection to evaluate Tag expression and use
RemoveByKey to remove unwanted items.
In this case security information if placed in every object property, no
central place to control.

4. Create menus dynamically from some class attributes or from some other
metadata.

Where to find more information and sample code ?
Which is best way for this ?

Andrus.
Peter Duniho - 13 Apr 2008 18:54 GMT
> [...]
> 3. Store access levels in Tag property in designer:
[quoted text clipped - 10 lines]
> Where to find more information and sample code ?
> Which is best way for this ?

I can't say that I know the _best_ way to do this.  However, it seems to  
me that with #3 you're on the right track.  However, rather than encoding  
security information in every object property, maybe you'd find it more  
structured to come up with some "security class" naming scheme that's  
applied to the tags instead.  Then, somewhere else in your program you use  
the class name to look up the specific security attributes.

At least that way you have the actual security settings centralized in one  
place.

Your #4 idea sounds reasonable too, though of course you'll have to come  
up with a good way to represent the menu data.

Also, I take as granted that this is simply for user convenience.  That  
is, even if the disallowed menu items showed up, the command would not  
actually be allowed to proceed if the user selected that.  I think that  
embedding actual security in the user interface side of your code isn't  
really all that secure, so hopefully that's not the intent here.

Pete
Marc Gravell - 14 Apr 2008 07:52 GMT
For reference, it would probably be pretty easy to extend the
"extension" role stuff (post over weekend) to do this - either with some
kind of delimited token (this+that+other), or by setting a master role
(or roles) on the component, with more specific roles on the extension
("foo on bar") - and insist that it has both.

I'm not going to mock it up, but it sounds like about half-an-hours work
from on top of what I posted the other day.

Marc
Andrus - 14 Apr 2008 09:54 GMT
Marc,

> For reference, it would probably be pretty easy to extend the "extension"
> role stuff (post over weekend) to do this - either with some kind of
> delimited token (this+that+other), or by setting a master role (or roles)
> on the component, with more specific roles on the extension ("foo on
> bar") - and insist that it has both.

I have authentication table in server containing columns

UserOrRoleName - John, Seller, Manager, Marc etc.
Privilege - Invoice, Order etc.
Access level -  Read, Write, Post etc.
Department  - Sales, Support  etc.

> I'm not going to mock it up, but it sounds like about half-an-hours work
> from on top of what I posted the other day.

I assume that you are referencing a code below.
I have no idea how using any .NET classes with this table to create
AccessLevel( UserOrRoleName, Privilege Department  ) function.
So it seems that I must implement my custom authentication.

Andrus.

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, string> map
           = 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;
       }
   }
stv.dmsk@gmail.com - 16 Apr 2008 14:37 GMT
> I have .NET 2 WinForms MDI application containing 250 ToolStripMenu items.
>
[quoted text clipped - 33 lines]
>
> Andrus.

Hi,

I'm not sure I understood perfectly what you need, but is seems you
can do what you need with this tool:
http://www.visual-guard.com/EN/.net-security-user-role-permission/identity-manag
ement-access-control-authentication-tool#admin


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.