MVC Authentication and Rights Management

Source: Internet
Author: User
Tags httpcontext ticket

http://www.cnblogs.com/asks/p/4372783.html MVC authentication and Rights Management

MVC comes with the Actionfilter

In the ASP. WebForm to be authenticated Microsoft provides us with three ways, the most commonly used is our form certification, need to configure the appropriate information. For example, the following configuration information:

<authentication mode= "Forms" >    <forms loginurl= "Login.aspx" defaulturl= "default.aspx" protection= "all" /></authentication><authorization>    <deny users= "?" />    <allow users= "*"/></authorization>

Description Our login page is login.aspx, the default page after login is default.aspx, and our user information is verified and encrypted in two ways. And the most important thing is that we have to write the authorization method (the following authorization must be written otherwise only the use of forms authentication and then set the related properties is not useful), deny all anonymous users, only the logged-on user can access the normal. Then we set the click login button to write the username into a cookie (that is, execute Formsauthentication.setauthcookie (name, false);).

We can also use Forms authentication in ASP. But if you do it in WebForm, you can't. For example, you configure information like this:

<authentication mode= "Forms" >    <forms loginurl= "~/account/login" defaulturl= "~/home/index" protection= "All"/></authentication><authorization>    <deny users= "?" />    <allow users= "*"/></authorization>

You set the login in Login.aspx to trigger logon in AccountController, where the logon code:

Public ActionResult Logon (string name,string password)    {        if (name = = "jianxin160" && password = = "160796"        {            Formsauthentication.setauthcookie (name, false);            Return Redirect ("~/home/index");        }        else    {            return Redirect ("/");        }    }

You will find that your logon will not be executed after this operation. What is the reason? Why is the same setup not going to be in MVC? The reason is that the two mechanisms are different because the authorization method you set up makes logon inaccessible. So how do we do it?

In fact, we have a better way to do this in ASP. We don't need authorization, which means our configuration information looks like this:

<authentication mode= "Forms" >    <forms loginurl= "~/account/login" defaulturl= "~/home/index" protection = "All"/></authentication>

You do not need to indicate that anonymous users cannot log on. Of course, you'll find that it's just not going to work. We also need to change the way we tell the system which needs to be logged in to access. You might think, O (︶^︶) o Alas, that's too much trouble. Not really, it's simple, we just need to mark [authorize] on the action that needs to be certified. For example, I have two pages in the Home folder index and home, I now want to have index authenticated to access, and home does not need, then only need to give index this action tag [authorize], that is:

[Authorize]    Public ActionResult Index ()    {        return View ();    }    Public ActionResult Home ()    {        return View ();    }

The index must be logged in before it can be accessed, and home does not need to be logged in. If you need a role authorization then you can specify the role (for example [Authorize (Role=administrators)]) When you mark authorize, but you must use the membership mechanism that Microsoft has given us. Because your role can not be a non-existent, but in the corresponding database, which I mentioned in another blog is not much to say.

Custom Actionfilter

Sometimes such certifications may not be available to you, or if you feel that you are not flexible enough, ASP. NET MVC allows you to customize the Actionfilter. For example I am now customizing identity authentication:

Using System;   Using System.Collections.Generic;   Using System.Linq;   Using System.Web;   Using SYSTEM.WEB.MVC;   Using System.Web.Security;    Namespace Formformsauthenticationmvc   {public       class Requiresauthenticationattribute:actionfilterattribute       {public           override void  onactionexecuting (actionexecutingcontext filtercontext)           {               if (! filterContext.HttpContext.User.Identity.IsAuthenticated)               {                   string returnUrl = FilterContext.HttpContext.Request.Url.AbsolutePath;                   String RedirectURL = String. Format ("? Returnurl={0} ", RETURNURL);                   String loginurl = Formsauthentication.loginurl + RedirectURL;                   FilterContext.HttpContext.Response.Redirect (loginurl, True);}}}   

If user management is required, I define role-related filter:

Using System;    Using System.Collections.Generic;    Using System.Linq;    Using System.Web;    Using SYSTEM.WEB.MVC;    Using System.Web.Security;            Namespace Mvcapplication1.myclass {public class Requiresroleattribute:actionfilterattribute {            public string Role {get; set;} public override void OnActionExecuting (ActionExecutingContext filtercontext) {if (!string.                    IsNullOrEmpty (Role)) {if (!filtercontext.httpcontext.user.identity.isauthenticated)                        {string returnUrl = FilterContext.HttpContext.Request.Url.AbsolutePath; String RedirectURL = String. Format ("?                        Returnurl={0} ", RETURNURL);                        String loginurl = Formsauthentication.loginurl + RedirectURL;                    FilterContext.HttpContext.Response.Redirect (loginurl, true);            } else {            BOOL isauthenticated = FilterContext.HttpContext.User.IsInRole (Role); if (!isauthenticated) {throw new UnauthorizedAccessException ("You have no r                ight to view the page! ");}}                else {throw new InvalidOperationException ("No Role specified!"); }            }        }    }

In fact, you will find the above two attribute in fact, the MVC authorized has been solved, here is mainly to tell you if you need to be able to expand.

All right, let's get here today! Source code Download: FORMFORMSAUTHENTICATIONMVC

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: The original accountcontroller to implement control inversion, forms authentication is abstracted. For demonstration convenience, I have removed this section (as well as the registration and modification of 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.

Code Download: Mvc-formsauthentication-rolesauthorization-1.rar (243KB)

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);        }    }    //...}

Code Download: Mvc-formsauthentication-rolesauthorization-2.rar (244KB)

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) {/**/}    /**/}

MVC Authentication and Rights Management

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.