Permission management I. ASP. NET Forms identity authentication and forms Identity Authentication

Source: Internet
Author: User

[Switch] permission management 1. ASP. NET Forms identity authentication and forms Identity Authentication

[Switch] permission management learning 1. ASP. NET Forms Identity Authentication

Note: VS2017 and MVC5 are used in this example.
The system is generally inseparable from registration and logon, regardless of its size, scalability, or dash. Next we will analyze the user identity authentication.

Simple login and logout

In the past, when I was studying. net, I didn't know what Forms Identity Authentication was. I used session to log on directly. The effect was quite good. In addition, user information is stored on the server and secure.
Front-end code:

@ If (string. isNullOrWhiteSpace (ViewBag. userName )) {<form action = "/home/login1"> <input type = "text" name = "userName"/> <input type = "submit" value = "Logon"/> </form >}else {<form action = "/home/logout1"> <div> the current user is logged on, login Name: @ ViewBag. userName </div> <input type = "submit" value = "quit"/> </form>}

Background code:

Public ActionResult Index () {ViewBag. UserName = Session ["userName"]?. ToString (); return View ();} public void Login1 (string userName) {if (! String. isNullOrWhiteSpace (userName) // For ease of demonstration, Session ["userName"] = userName; else Session ["userName"] = null; Response. redirect (Request. urlReferrer. localPath); // redirect to the original page} public void Logout1 () {Session ["userName"] = null; Response. redirect (Request. urlReferrer. localPath); // redirect to the original page}

Is it simple and clear. It is useful to extend or customize any features on your own. However, we need to maintain the session. For example, the system is re-released, or iis is automatically restarted. The session will be lost. That is, the user will be inexplicably promoted and need to log on again. Poor experience. (The session service and database are not discussed here ). Since Microsoft has a set of mature permission management systems, why not?

Forms authentication logon and logout

First, enable Forms authentication in web. config:

<system.web>  <authentication mode="Forms"></authentication>

Background code:

Public void Login2 (string userName) {if (! String. isNullOrWhiteSpace (userName) // FormsAuthentication is not verified for ease of demonstration. setAuthCookie (userName, true); // log on to Response. redirect (Request. urlReferrer. localPath); // redirect to the original page} public void Logout2 () {FormsAuthentication. signOut (); // logout Response. redirect (Request. urlReferrer. localPath); // redirect to the original page}

Front-end code:

@ If (! Request. isAuthenticated) {<form action = "/home/login2"> <input type = "text" name = "userName"/> <input type = "submit" value = "Logon"/> </form >}else {<form action = "/home/logout2"> <div> the current user is logged on, login Name: @ Context. user. identity. name </div> <input type = "submit" value = "exit"/> </form>}

Such a few codes enable logon and logout. It is different from using session management to log on. Forms authentication directly saves information to the browser. You can also see the method name through SetAuthCookie. However, the Cookie information is encrypted.
It is necessary to describe the relationship between session and cookie. When we use session to maintain the user status, we also use cookies.

However, Forms authentication only stores information in cookies, but does not maintain a session on the server.
If you don't believe it, you can test it. You can log on in either of the two methods, and then clear the session. (How to clear the session? Restart iis, or modify the background code to re-compile and access)
[Note] Why do I need to store cookies for user authentication? Because HTTP is a stateless protocol. For the server, each request is the same. Therefore, users can only be identified by the cookie contained in each request. (Other methods are not considered for the moment)

Custom Identity Authentication

The above logon is simple, but the actual situation is often complicated. Obviously, more user information is required for normal services. Can we extend the identity? The answer is yes.
Background code:

Public void Login3 (string userName) {if (! String. isNullOrWhiteSpace (userName) // For ease of demonstration, {UserInfo user = new UserInfo () {Name = userName, LoginTime = DateTime. now}; // 1. serialize the user information to be saved var data = JsonConvert. serializeObject (user); // 2. Create a FormsAuthenticationTicket that contains the login name and additional user data. FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (2, userName, DateTime. now, DateTime. now. addDays (1), true, data); // 3. encrypt and save string cookieValue = FormsAuthentication. encrypt (ticket); // 4. create a logon Cookie HttpCookie cookie = new HttpCookie (FormsAuthentication. formsCookieName, cookieValue); cookie. httpOnly = true; cookie. secure = FormsAuthentication. requireSSL; cookie. domain = FormsAuthentication. cookieDomain; cookie. path = FormsAuthentication. formsCookiePath; // 5. write the logon Cookie Response. cookies. remove (cookie. name); Response. cookies. add (cookie);} Response. redirect (Request. urlReferrer. localPath); // redirect to the original page}

Then the Application_AuthenticateRequest method in Global. asax is as follows:

Protected void Application_AuthenticateRequest () {GetUserInfo ();} // read user information to HttpContext through coolie decryption. current. userpublic void GetUserInfo () {// 1. read login Cookie HttpCookie cookie = Request. cookies [FormsAuthentication. formsCookieName]; try {UserInfo userData = null; // 2. decrypts the Cookie value and obtains the FormsAuthenticationTicket object FormsAuthenticationTicket ticket = FormsAuthentication. decrypt (cookie. value); if (ticket! = Null & string. isNullOrEmpty (ticket. userData) = false) // 3. restore user data userData = JsonConvert. deserializeObject <UserInfo> (ticket. userData); if (ticket! = Null & userData! = Null) // 4. Construct Our MyFormsPrincipal instance and assign a value to context. User. HttpContext. Current. User = new MyFormsPrincipal <UserInfo> (ticket, userData);} catch {/* exceptions should not be thrown to prevent attackers from testing. */}}

Front-end code:

@ {MyFormsPrincipal <UserInfo> user = Context. user as MyFormsPrincipal <UserInfo>; if (user = null) {<form action = "/home/login3"> <input type = "text" name = "userName"/> <input type = "submit" value = "Logon"/> </form >}else {<form action = "/home/logout2"> <div> the current user is logged on, login Name: @ Context. user. identity. name </div> <div> the current user has logged on. Logon Time: @ user. userData. loginTime </div> <input type = "submit" value = "quit"/> </form> }}

In fact, the entire process andFormsAuthentication. SetAuthCookie (userName, true); // log onIs equivalent. We only store the data we want to store through expansion.
The process is also relatively simple:

  • Construct the data to be stored
  • Serialization
  • Put the serialization information into the FormsAuthenticationTicket object
  • Use FormsAuthentication. Encrypt to Encrypt an object
  • Send cookie to Browser

Here, it is a little complicated to decrypt and assign a value to the User.HttpContext.Current.User = new MyFormsPrincipal<UserInfo>(ticket, userData);.
MyFormsPrincipal interface MyFormsPrincipal

Public class MyFormsPrincipal <TUserData>: IPrincipal where TUserData: class, new () {private IIdentity _ identity; private TUserData _ userData; public MyFormsPrincipal (FormsAuthenticationTicket ticket, TUserData userData) {if (ticket = null) throw new ArgumentNullException ("ticket"); if (userData = null) throw new ArgumentNullException ("userData "); _ identity = new FormsIdentity (ticket); _ userData = userData;} public TUserData UserData {get {return _ userData ;}} public IIdentity Identity {get {return _ identity ;}} public bool IsInRole (string role) // {return false;} is not implemented at the moment ;}}

There is nothing special about it, that is, it is enough to pass in the ticket and custom data during instantiation.

Authorization

With logon, authorization is generally not required. Microsoft is doing a good job. Generally, it is a complete set of items.

[Authorize]public ActionResult LoginOk(){    return View();}

Simply add an Authorize feature to the Action, and this person will automatically check whether or not to log on. If you do not log on, the logon page is automatically displayed. The logon page settings are still in web. config.

<system.web>  <authentication mode="Forms" >    <forms loginUrl="/home/index"></forms>

This simple authentication is obviously not enough. In many cases, only some people can access some pages. For example, VIP. So we have to expand again.

// Inherit AuthorizeAttributepublic class MyAuthorizeAttribute: AuthorizeAttribute {public override void OnAuthorization (AuthorizationContext filterContext) {if (filterContext. HttpContext. User. Identity. Name! = "Farm Code life") {filterContext. httpContext. response. write ("You are not a vip user and cannot access confidential data"); filterContext. httpContext. response. end (); return;} base. onAuthorization (filterContext );}}
[MyAuthorize]public ActionResult LoginVIP(){    return View();}

Yes, it's that simple. If you have said so much, come to Zhang:

 

Recommended reading:

  • Http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html
    Demo:
  • Https://github.com/zhaopeiym/blogdemocode/tree/master/permission management /1-formsid Authentication

 

Related Article

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.