ASP. NET MVC builds on ASP. Many of the features of ASP (such as forms authentication, membership) can be used directly in MVC. This article is intended to provide reference code that does not involve too much theoretical knowledge in this area.
This article uses only ASP. Forms authentication and does not use its membership (membership) and role Management (rolemanager) for two reasons: inflexible, and less than MVC.
First, sample project
User.cs is a model file that contains the User class:
public class user{Public int ID {get; set;} public string Name {get; set;} public string Password {get; set;} Public string[] Roles {get; set; }}
Userrepository is a data access class that, for demonstration convenience, does not connect to a database, but instead uses an array as the data source:
public class userrepository{ private static user[] Usersfortest = new[]{ new user{ID = 1, Name = "Bob", Password = "Bob", Roles = new []{"Employee"}, new user{ID = 2, Name = "Tom", Password = "Tom", Roles = new []{"manager"}},
new user{ID = 3, Name = "admin", Password = "admin", Roles = new[]{"Admin"}}, }; public bool ValidateUser (string userName, string password) { return usersfortest . Any (U = u.name = = UserName && U.password = = Password); } Public string[] GetRoles (string userName) { return usersfortest . Where (U = u.name = = userName) . Select (U = u.roles) . FirstOrDefault (); } Public User Getbynameandpassword (string name, string password) { return usersfortest . FirstOrDefault (U = u.name = = Name && U.password = = Password);} }
Second, the user login and authentication method one
Modify AccountController: original AccountController to implement control inversion, forms authentication is abstracted. For demonstration convenience, I'm going to go beyond this section (and register and change the password section):
public class accountcontroller:controller{ private userrepository repository = new Userrepository (); Public ActionResult LogOn () { return View (); } [HttpPost] Public ActionResult LogOn (Logonmodel model, string returnUrl) { if (modelstate.isvalid) { if ( Repository. ValidateUser (model. UserName, model. Password)) { Formsauthentication.setauthcookie (model. UserName, model. RememberMe); if (! String.IsNullOrEmpty (RETURNURL)) return Redirect (RETURNURL); else return redirecttoaction ("Index", "Home"); } else Modelstate.addmodelerror ("", "username or password is incorrect!) "); } return View (model); } Public ActionResult LogOff () { formsauthentication.signout (); Return redirecttoaction ("Index", "Home");} }
Modify Global.asax:
public class mvcapplication:system.web.httpapplication{public mvcapplication () { AuthorizeRequest + = New EventHandler (mvcapplication_authorizerequest); } void Mvcapplication_authorizerequest (object sender, EventArgs e) { IIdentity id = Context.User.Identity; if (ID. isauthenticated) { var roles = new Userrepository (). GetRoles (ID. Name); Context.User = new GenericPrincipal (ID, roles); } } //...}
Add a constructor to mvcapplication that adds a handler for the AuthorizeRequest event.
Way Two
This method saves the user's role to the user Cookie and uses the FormsAuthenticationTicket.
Modify AccountController:
public class accountcontroller:controller{Private userrepository repository = new Userrepository (); Public ActionResult LogOn () {return View (); } [HttpPost] public actionresult LogOn (Logonmodel model, string returnUrl) {if (modelstate.isvalid) {User user = Repository. Getbynameandpassword (model. UserName, model. Password); if (user! = null) {FormsAuthenticationTicket ticket = new FormsAuthenticationTicket ( 1, user. Name, DateTime.Now, DateTime.Now.Add (formsauthentication.timeout), Model. RememberMe, user. Roles.aggregate ((i,j) =>i+ "," +j)); HttpCookie cookie = new HttpCookie (Formsauthentication.formscookiename, Formsauthen Tication. Encrypt (ticket)); Response.Cookies.Add (COOKie); if (! String.IsNullOrEmpty (RETURNURL)) return Redirect (RETURNURL); else return redirecttoaction ("Index", "Home"); } else Modelstate.addmodelerror ("", "username or password is incorrect!) "); } return View (model); } public ActionResult LogOff () {formsauthentication.signout (); Return redirecttoaction ("Index", "Home"); }}
Modify Global.asax:
public class mvcapplication:system.web.httpapplication{public mvcapplication () { AuthorizeRequest + = New EventHandler (mvcapplication_authorizerequest); } void Mvcapplication_authorizerequest (object sender, EventArgs e) { var id = Context.User.Identity AS formsidentity; if (id! = NULL && ID. isauthenticated) { var roles = ID. Ticket.UserData.Split (', '); Context.User = new GenericPrincipal (ID, roles); } } //...}
Third, role permissions
With either approach, we can use Authorizeattribute in the Controller to implement role-based rights management:
[Authorize (Roles = "Employee,manager")]public ActionResult Index1 () { return View ();} [Authorize (Roles = "manager")]public ActionResult Index2 () { return View ();} [Authorize (users= "admin", Roles = "admin")]public actionresult Index3 () { return View ();}
Iv. Brief description
MVC uses the HttpContext.User property to implement authentication and role management, as well as authorizeattribute role authorization based on HttpContext.User.
Because some do not after the user login, the relevant user information in the session (often seen on the internet), it is a very bad practice to save the user in the session.
Also do not judge role permissions in the Action, you should use Authorizeattribute or its subclasses, the following methods are wrong :
Public ActionResult Action1 () { if (session["User"] = = null) {/**/} /**/}public ActionResult Action2 () { if ( User.Identity = = null) {/**/} if (User.Identity.IsAuthenticated = = False) {/**/} if (User.IsInRole ("admin") = = f alse) {/**/} /**/}
ASP. NET MVC: Forms authentication and role Rights Management example