Previous ArticleArticleWe briefly introduce the application of a level-1 menu.
In actual design, the menu information is basically stored in the XML file of sitemap, And the menu also involves permissions.
This chapter describes how to design a rule-based MVC application.ProgramSecurity.
Role-based authorization
Role-Based Access Control (RBAC) is a method to restrict access to authorized users in computer systems. The job functions created by roles within an organization. To assign permissions for certain operations to specific roles.
In terms of business, we must define a role system for different business functions, such as administrator, Data Administrator, and common user roles ......
Rule-Based Access Control
A rule-based authorization framework generally uses XML documents to store simple rule settings to control system access permissions. (It can also be stored in the database, and readers can expand the Enterprise Library)
See the following example.
< Rules >
< Add Expression = "R: Administrator" Name = "Isadministrator" />
< Add Expression = "R: Administrator or R: datasteward" Name = "Isdatasteward" />
< Add Expression = "R: user or R: datasteward or R: Administrator" Name = "Isuser" />
</ Rules >
The rule "isadministrator" checks whether the current user has the administrator role. "Isuser" is valid for both the Role user, datasteward, and administrator.
Securityhelper
The securityhelper class utilizes the default authorizationruleprovider of the Enterprise Library, which is the core of our entire system.
Check the validity of a rule for the current user.CodeAs follows.
Iauthorizationprovider auth = authorizationfactory. getauthorizationprovider ("rulesprovider"); If (rules. Count> 0 & sessionwrapper. currentuser. Principal! = NULL) {foreach (string rule in Rules) {// authorize user (with its roles) agains the Rule If (! Auth. Authorize (sessionwrapper. currentuser. Principal, rule) {return false ;}} else {return false;} return true;
Menu access control
In the Web. sitemap file, we add an attribute to each node. In this way, the menu is associated with the user role.
<? XML version = "1.0" encoding = "UTF-8" ?>
< Sitemap Enablelocalization = "True" >
< Sitemapnode Title = "Menu" >
< Sitemapnode Controller = "Home" Title = "Home" Action = "Index" Resourcekey = "Tab_home" Authorizationrule = "Isuser" />
< Sitemapnode Controller = "Customer" Title = "Manage MERs" Action = "Index" Resourcekey = "Tab_managecustomers" Authorizationrule = "Isdatasteward" />
< Sitemapnode Title = "Switching brands" Resourcekey = "Tab_switchingbrands" Authorizationrule = "Isuser" >
< Sitemapnode Title = "Violin" Controller = "Home" Action = "Settheme/Violin" Authorizationrule = "Isuser" />
< Sitemapnode Title = "Mack" Controller = "Home" Action = "Settheme/Mack" Authorizationrule = "Isuser" />
< Sitemapnode Title = "Mack dual" Controller = "Home" Action = "Settheme/macdual" Authorizationrule = "Isuser" />
< Sitemapnode Title = "Renault" Controller = "Home" Action = "Settheme/Renault" Authorizationrule = "Isuser" />
< Sitemapnode Title = "Volvo ba" Controller = "Home" Action = "Settheme/volvoba" Authorizationrule = "Isuser" />
< Sitemapnode Title = "Volvo Group" Controller = "Home" Action = "Settheme/volvogroup" Authorizationrule = "Isuser" />
</ Sitemapnode >
</ Sitemapnode >
</ Sitemap >
How and when are menu rules loaded? In the sitemapbinding. cshtml file of the rendering menu, our code is as follows. (The example uses the telerik for Asp.net MVC control)
@ Using customermaster. Web. Common. Security
@ Using customermaster. Web
@ {Html. telerik (). menu ()
. Name ("menu ")
. Bindto ("Web", (item, node) => {
If (node. attributes ["resourcekey"]! = NULL)
Item. Text = ui_resources.resourcemanager.getstring (node. attributes ["resourcekey"] as string )?? Item. text;
If (node. attributes ["imageurl"]! = NULL)
Item. imageurl = node. attributes ["imageurl"]. tostring ();
Item. Visible = securityhelper. Authorized (node. attributes ["authorizationrule"]. tostring ());
})
. Effects (FX =>
FX. Toggle ()
. Openduration (200)
. Closeduration (200 ))
. Render ();
}
Here, item. Visible = securityhelper. Authorized (node. attributes ["authorizationrule"]. tostring (); this line of code determines that the menu visibility is controlled by the rules we define.
UI element Access Control
With the same principle, the enable/disable of the button can also be controlled based on rules. We first construct an htmlhelper class to display buttons on the page.
The following core code associates the display of permission rules with buttons.
Private Static string button (this htmlhelper helper, string name, string buttontext, bool disabled, ienumerable htmlattributes)
{< br> htmlgenericcontrol A = new htmlgenericcontrol ("input");
. id = Name;
. attributes ["name"] = Name;
. attributes ["value"] = buttontext;. attributes ["type"] = "button";
If (disabled). attributes ["disabled"] = "Disabled";
If (htmlattributes! = NULL)
foreach (keyvaluepair attribute in htmlattributes)
{< br>. attributes [attribute. key] = attribute. value. tostring ();
}< br> stringbuilder htmlbuilder = new stringbuilder ();
htmltextwriter htmlwriter = new htmltextwriter (New stringwriter (htmlbuilder ));
string html = htmlbuilder. tostring ();
return HTML;
}
On the page, how do we use buttonhelper? The following example uses telerik to display a grid. The edit, add, and delete buttons are displayed on the grid header.
The button generation uses my buttonhelper class. It provides some extension methods.
@ (Html. telerik (). Grid <customer> ()
. Name ( " Customergrid " )
. Enablecustombinding ( True )
. Databinding (BIND => bind. Ajax (). Select ( " Listcustomerajax " , " Customer " ))
. Toolbar (toolbar => toolbar. Template
(
@ Html. Button ( " Toolbareditrow " , Ui_resources.listcustomer_editcustomerbutton,
Buttonhelper. setbuttondisability ( " Toolbareditrow " , " Isadministrator " ),
New {Title = ui_resources.listcustomer_editcustomerbuttontooltip, @ class = " Icon Edit " })
+ " <Span> & nbsp; </span> " +
@ Html. Button ( " Toolbaraddrow " , Ui_resources.listcustomer_addnewcustomerbutton, buttonhelper. setbuttondisability ( " Toolbaraddrow " , " Isadministrator " ), New {Title = ui_resources.listcustomer_addnewcustomerbuttontooltip, @ class = " Icon add " })
+ " <Span> & nbsp; </span> " +
@ Html. Button (" Toolbardeleterow " , Ui_resources.listcustomer_deletecustomerbutton, buttonhelper. setbuttondisability ( " Toolbardeleterow " , " Isadministrator " ), New {Title = ui_resources.listcustomer_deletecustomerbuttontooltip, @ class = " Icon Delete " })
))
...
When the button is displayed, we call buttonhelper. setbuttondisability to control the enable/disable status of the button. We can also use it to control the display and not display buttons.
MVC controller class Access Control
Some users may directly enter a URL in the browser to bypass menu permission control. We must add our rule-based permission management at the Controller level of MVC.
We add a new class ruleauthorizeattribute, which inherits from system. web. MVC. authorizeattribute, which uses the securityhelper function for security review. Because the Copyright Code is omitted, readers can use Google-related code.
We will set this property in the customercontroller class in the example program.
[Handleerror]
[Ruleauthorize (allow ="Isdatasteward")]
Public ClassCustomercontroller: basecontroller
{
}
Assume that the user we log on to does not have the datasteward or administrator role, but he attempts to directly enter URL: http: // localhost: 2967/customer in the browser.
The new filter controls the permission management of direct URLs.
Button Display Control
Design Features
1) The architecture is rule-based and easy to configure, with the tedious database table design omitted (User Role and other information can be implemented using membership)
2) Rules can be stored in the database and imported into the Cache during system initialization. Subsequent user permission management is completely out of the database, improving the overall system performance.
3) Rules can be adapted to menu items, page controls, and business logic components to achieve permission management at all levels and levels of the system. Development Code follows the unified mode.
4) In actual applications, you can add page maintenance rules and role ing relationships so that the roles are unrestricted, you can pre-define individual access rules for menu items with the same permission control or control groups,
The system only needs to add a new rule and maintain the role group corresponding to the rule to achieve dynamic control.