C # WEBAPI----H5_app Background production (1)--Certification

Source: Internet
Author: User
Tags decrypt ticket

1, recently received a H5, the app backstage project, want to use WEBAPI do backstage encountered some problems,

(1) Question one: The user's authentication method,

First, why need identity authentication

In the preface, we have said that if authentication is not enabled, any anonymous user who knows the URL of our service will be able to access or modify the database by accessing our service interface as freely as possible.

1, we do not add identity authentication, anonymous users can directly through the URL arbitrary Access interface:

As you can see, anonymous users can access our data interface directly through the URL, and what will happen eventually, you can imagine.

2. After the identity authentication is added, only the request to access the ticket can access our interface.

For example, if we access directly via URL, we will return 401

If it is a normal process request, with the ticket, it is OK.

As you can see, the request for a normal process adds authorization to the header of the request message, and its value is our ticket ticket information.

Back to the top second, basic Basic authentication principle analysis back to top 1, common authentication methods

We know that there are many kinds of authentication mechanisms for ASP. For Webapi is no exception, the common authentication method has

    • Form Identity Verification
    • Integrated Windows Authentication
    • Basic BASIC Certification
    • Digest Digest Certification

There are many articles about WEBAPI certification in the garden, all kinds of authentication methods will be involved, but the feeling is not thin enough. There is no need to study which authentication method is suitable for which use scenario, because bloggers still feel "can chew", may also be limited by the ability of Bo master. For the authentication mechanism, understand one of them, others can digest. This article uses basic basic certification to explain the whole process in detail.

Back to top 2, basic Basic Authentication principle

We know that the purpose of certification is to be safe, so how can we ensure security? The usual means of nature is encryption. Basic authentication is no exception, the main principle is to encrypt user information, generate tickets, each time the request will be brought to verify the bill. This may be a bit abstract, we break down each step in detail:

    1. First login to verify the user name, password, if the login is successful, then the user name, password according to certain rules to generate encrypted ticket information ticket, the ticket information back to the front.
    2. If the login is successful, the front end will receive the ticket information, and then jump to the main interface, and the ticket information is also taken to the main interface ActionResult inside (such as the URL of the jump can be written like this:/home/index? Ticket=ticket)
    3. In the main interface of the ActionResult through the parameters to get ticket information ticket, and then save ticket information to viewbag inside the front.
    4. At the front of the main interface, when sending an AJAX request, the ticket information is added to the requested head, and the ticket information is sent to the service side along with the request.
    5. Within the WEBAPI service, define a class, inherit the Authorizeattribute class, and then override the Onauthorization method of the parent class, taking the head of the current HTTP request in the Onauthorization method, Get the information from the head that comes from our front end. Decrypt the ticket information, obtain the user name and password from the decrypted information, and then verify that the user name and password are correct. If it is correct, the validation passes, otherwise the unauthenticated request 401 is returned.

This basic principle. Follow this principle to see how each step of the code is implemented.

Back to the top three, basic basic certification Code examples

Let's start with our example scenario where we put two Project Web and webapicors in a solution last time we introduced CORS, and we'll use this as an example to illustrate this.

Back to top 1, login process 1.1, web front end
<body>    <div style= "Text-align:center;" >         <div> User name: <input type= "text" id= "Txt_username"/></div>        <div> secret  code:< Input type= "password" id= "Txt_password"  /></div>        <div><input type= "button" value= "Login" id= "Btn_login" class= "Btn-default"/></div>    </div></body>
$ (function () {    $ ("#btn_login"). Click (function () {        $.ajax ({            type: "Get",            URL: "http://localhost : 27221/api/user/login ",            data: {struser: $ (" #txt_username "). Val (), Strpwd: $ (" #txt_password "). Val ()},            Success:function (data, status) {                if (status = = "Success") {                    if (!data.bres) {                        alert ("Login Failed");                        return;                    }                    Alert ("Login successful");
After successful login, bring the user name and user ticket to the main interface window.location = "/home/index?" Username= "+ data. UserName + "&ticket=" + data. Ticket; } , error:function (e) { }, complete:function () { } } );});
1.2. Login API Interface
   public class Usercontroller:apicontroller {//<summary>//USER Login///</summary> <param name= "struser" ></param>//<param name= "strpwd" ></param>//&lt            ;returns></returns> [HttpGet] public Object Login (String struser, String strpwd) { if (!            ValidateUser (struser, strpwd)) {return new {bRes = false};                            } FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (0, struser, DateTime.Now, DateTime.Now.AddHours (1), True, string.            Format ("{0}&{1}", struser, Strpwd), Formsauthentication.formscookiepath); Returns login results, user information, user authentication ticket information var ouser = new UserInfo {BRes = true, UserName = struser, Password = strpwd, Ticket =            Formsauthentication.encrypt (Ticket)}; Save the identity information in the session to verify that the current request is a valid request HttpContext.Current.SessioN[struser] = ouser;        return ouser; }//Verify user name password (should be database checksum in formal environment) private bool ValidateUser (string struser, String strpwd) {if (            struser = = "Admin" && strpwd = = "123456") {return true;            } else {return false;        }}} public class UserInfo {public bool BRes {get; set;}        public string UserName {get; set;}        public string Password {get; set;}    public string Ticket {get; set;} }

One thing to note here is that since WEBAPI does not open the session by default, we need to configure it manually to enable the session. How to open the session inside the WEBAPI, please refer to: http://www.cnblogs.com/tinya/p/4563641.html

As the above-mentioned principle, the login if the failure, the direct return, if successful, will generate the ticket ticket to the front end, to the main interface/home/index, below, we will look at the main interface Home/index.

Back to top 2,/home/index main interface
public class Homecontroller:controller    {        //get:home public        actionresult Index (String UserName, String Tic KET)        {            viewbag.username = UserName;            Viewbag.ticket = Ticket;            return View ();        }    }
$ (function () {    $.ajax ({        type: "Get",        URL: "Http://localhost:27221/api/Charging/GetAllChargingData",        data: {},        beforesend:function (XHR) {            ///Send Ajax request to HTTP head inside to add authentication information            xhr.setrequestheader (' Authorization ', ' BasicAuth ' + Ticket);        },        success:function (data, status) {            if (status = = "Success") {                $ ("#div_test"). HTML (data);            }        },        error:function (e) {            $ ("#div_test"). HTML ("error");        complete:function () {        }    });

What needs to be explained here is that, before we send the AJAX request, we pass the xhr.setrequestheader (' Authorization ', ' BasicAuth ' + Ticket), which adds the ticket information to the request's message header. This is because this sentence is added here, so we have the Red line part:

Back to top 3, webapicors verification Section (emphasis)

We see that the/home/index page above sends an AJAX request to access the service's Http://localhost:27221/api/Charging/GetAllChargingData interface, So how do we verify this request and the legitimate request in WEBAPI? Next we'll focus on the verification process.

3.1, in the Webapicors project to customize a class Requestauthorizeattribute, to inherit our Authorizeattribute this class. Then rewrite the Onauthorization method, in this method to fetch the ticket information of the request header, and then verify the user name password is reasonable.
   <summary>////Customize this attribute for interface authentication///</summary> public class Requestauthorizeattribute:authoriz Eattribute {//overrides the base class validation method, add our custom ticket to verify public override void Onauthorization (System.Web.Http.Controller S.httpactioncontext actioncontext) {//Obtain authentication information from the HTTP request's header to verify that it is the ticket var authorizatio of the requesting initiator            n = actionContext.Request.Headers.Authorization; if (authorization! = NULL) && (authorization. Parameter = null)) {//Decrypt user ticket and verify that the user name password matches var encryptticket = authorization .                Parameter; if (Validateticket (Encryptticket)) {base.                IsAuthorized (Actioncontext);                } else {handleunauthorizedrequest (actioncontext); }}//If authentication information is not available and anonymous access is not allowed, return unverified 401 else {var attributes = a Ctioncontext.aCtiondescriptor.getcustomattributes<allowanonymousattribute> ().                Oftype<allowanonymousattribute> (); BOOL isanonymous = attributes.                Any (a = A is allowanonymousattribute); if (isanonymous) base.                Onauthorization (Actioncontext);            else Handleunauthorizedrequest (Actioncontext); }}//verify user name password (should be database checksum in formal environment) private bool Validateticket (string encryptticket) {// Decrypt ticket var strticket = Formsauthentication.decrypt (encryptticket).            UserData;            Get username and password from ticket var index = strticket.indexof ("&");            String struser = strticket.substring (0, index);            String strpwd = strticket.substring (index + 1);            if (struser = = "Admin" && strpwd = = "123456") {return true;            } else {return false; }        }    }
3.2, in the specific API interface to increase the characteristics of our custom class above
    [Requestauthorize]    public class Chargingcontroller:apicontroller {//<summary>///For        all data//        </summary> ///        <returns> return Data </returns>        [HttpGet]        public string Getallchargingdata ()        {            return "Success";        }        <summary>///        get all data for the current ID///</summary>//        <param name= "id" > Parameters id</param >        ///<returns> return Data </returns>        [httpget] public        string getallchargingdata (string id)        {            return "chargingdata" + ID;        }    }

After adding the feature callout, each time the interface inside the API is requested, the program will first enter into the onauthorization () method that we override, and after the validation is passed, it will go into the corresponding method to execute, otherwise it returns 401.

Back to top four, optimize

Through the above steps, the basic can achieve the identity of the authentication we want to effect, but always feel not very convenient, the main less convenient points have the following several.

    1. Each time you create a new API, the corresponding interface will be labeled [requestauthorize] This one thing, feel good trouble.
    2. Each time you send an AJAX request, add xhr.setrequestheader (' Authorization ', ' BasicAuth ' + Ticket) in the Beforesend event, and this, too, feels troublesome.
    3. If there are some methods of WEBAPI service, we do not want to use this authentication so that it can be authenticated by anonymous users (such as our login method login). What to do with it.

Regarding the above two points, we optimize the

Back to top 1, solve the API problem

Add a common parent class to the API and Mark [Requestauthorize] on the parent class .

namespace webapicors.controllers{    [requestauthorize]    [Enablecors (Origins: "*", Headers: "*", Methods: "*")] Public    class Baseapicontroller:apicontroller    {    }}
namespace webapicors.controllers{public    class Chargingcontroller:baseapicontroller    {//        <summary >//Get all data///</summary>//        <returns> return Data </returns>        [HttpGet]        public String Getallchargingdata ()        {            return "Success";        }        <summary>///        get all data for the current ID///</summary>//        <param name= "id" > Parameters id</param >        ///<returns> return Data </returns>        [httpget] public        string getallchargingdata (string id)          {            return "chargingdata" + ID;        } }}

Note: We do not need to verify the login request, because the login time has not generated the ticket, so the login API can not inherit baseapicontroller

Back to top 2, solving the problem of Ajax

Remember that we are in the JS component series-Packaging their own JS components, you can also be introduced in this article to increase the AJAX error event public processing method? Can we use the same mechanism to increase this? Create a new file Jquery_ajax_extention.js

(function ($) {//1. $.ajax object var _ajax = $.ajax; $.ajax = function (options) {//2. Defines the default error handling method for each call to send an AJAX request var fn = {Error:function (xmlht Tprequest, Textstatus, Errorthrown) {toastr.error (xmlhttprequest.responsetext, ' error message ', {closebutton:true            , timeout:0, Positionclass: ' Toast-top-full-width '}); }, Success:function (data, textstatus) {}, Beforesend:function (XHR) {}, Complete:fu Nction (XHR, TS) {}}//3. Extend the native $.ajax method, return the latest parameter var _options = $.extend ({}, {Error:func            tion (XMLHttpRequest, textstatus, Errorthrown) {fn.error (XMLHttpRequest, Textstatus, Errorthrown);            }, Success:function (data, textstatus) {fn.success (data, textstatus);                }, Beforesend:function (XHR) {xhr.setrequestheader (' Authorization ', ' BasicAuth ' + Ticket); Fn.beforesend (XHR);            }, Complete:function (XHR, ts) {fn.complete (XHR, TS);        }}, options);    4. Pass the latest parameters back to the Ajax object _ajax (_options); };}) (JQuery);

Quoting this JS and then sending Ajax does not have to be written in the beforesend of each request.

Back to top 3, solve special don't want to use verification method

If some of our methods do not want to use validation so that it can be accessed by anonymous users, we can add a feature callout [allowanonymous] on top of the method, declaring that the method runs anonymous access. For example:

public class Chargingcontroller:baseapicontroller {//<summary>///        </summary >        ///<returns> return Data </returns>        [httpget] public        string Getallchargingdata ()        {            return "Success";        }        <summary>///        get all data for the current ID///</summary>//        <param name= "id" > Parameters id</param >///        <returns> return Data </returns>        [HttpGet]        [allowanonymous] public        string  Getallchargingdata (string id)        {            return "chargingdata" + ID;        } }
Back to top v. Summary

The above combined with an example of the basic certification of the implementation of the principle and simple use, the view of this article is from the blogger's own understanding, if there is not comprehensive place, but also hope that the Garden friends treatise. If this article can more or less help you, may wish to help recommend , Bo Master must continue to work ~ ~

Source: http://www.cnblogs.com/landeanfen/p/5287064.html

The reference to this article is very well written.

But I'm having a problem with it! The parameter is not received when the argument is passed.

C # WEBAPI----H5_app Background production (1)--Certification

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.