Permission authentication: yes, HTTP addresses are public, so permission authentication is required

Sessions – WebAPI does not support sessions by default – RESTful – can be extended to support this

Stateless: The second request is not associated with the first request

1 During login, obtain the token, token, ticket, and license

2 Successful authentication – Account + Password + Other information + time – Obtain ticket after encryption – Return the authentication to the client

3 when you make a request, you put this ticket (header) inside your Ajax

When the 4 interface is called, we’re going to validate the ticket, decrypt it, look at the message, look at the time

5 Each method requires ticket verification and is implemented based on filter

The back-end API for the user to log in and return a token

#regionThe user login
[CustomAllowAnonymousAttribute]
[HttpGet]
public string Login(string account, string password)
{
    if ("Admin".Equals(account) && "123456".Equals(password))// The database should be checked
    {
        FormsAuthenticationTicket ticketObject = new FormsAuthenticationTicket(0, account, DateTime.Now, DateTime.Now.AddHours(1), true.string.Format("{0} and {1}", account, password), FormsAuthentication.FormsCookiePath);
        var result = new
        {
            Result = true,
            Ticket = FormsAuthentication.Encrypt(ticketObject)
        };
        return JsonConvert.SerializeObject(result);
    }
    else
    {
        var result = new { Result = false };
        returnJsonConvert.SerializeObject(result); }}#endregion
Copy the code

User login front end, obtain token

$("#btnLogin").on("click", function () {
   $.ajax({
       url: "/api/users/Login",
       type: "GET",
       data: { "Account": $("#txtAccount").val(), "Password": $("#txtPassword").val() },
       success: function (data) {
           var result = JSON.parse(data);
           if (result.Result) {
               ticket = result.Ticket;
               alert(result.Ticket);
           }
           else {
               alert("failed");
           }
       }, datatype: "json"
   });
});

var ticket = "";// After login, put it in an HTML file
Copy the code

Requested by the user, with the preceding access token

Front end version

$("#btnGet1").on("click", function () {
    //$.ajax({ url: "/api/users", type: "get", data: { "userName": "Superman" }, success: function (data) { alert(data); }, datatype: "json" }); // Point to the interface, parameter matching, case insensitive
    $.ajax({
        //url: "/api/users/GetUserByName? ticket=" + ticket
        url: "/api/users/GetUserByName", type: "get", data: { "username": "Superman" },
        beforeSend: function (XHR) {
            // Add validation information to the HTTP head before sending ajax requests
            XHR.setRequestHeader('Authorization'.'BasicAuth ' + ticket);
        },
        success: function (data) {
            alert(data);
        }, datatype: "json"
    });
});
Copy the code

The back-end version

#regionThe user logs in to obtain ticket
private void AuthorizationDemo()
{
    string ticket = "";
    {
        string loginUrl = "http://localhost:8088/api/users/Login? Account=Admin&Password=123456";
        var handler = new HttpClientHandler();//{ AutomaticDecompression = DecompressionMethods.GZip };

        using (var http = new HttpClient(handler))
        {
            var response = http.GetAsync(loginUrl).Result;// get the asynchronous result
            Console.WriteLine(response.StatusCode); // Ensure the HTTP success status value
                                                    / / await asynchronous read last JSON (note that the gzip automatically extract had been made, and because of the above AutomaticDecompression = DecompressionMethods. Gzip)
            ticket = response.Content.ReadAsStringAsync().Result.Replace("\"{\\\"Result\\\":true,\\\"Ticket\\\":\\\""."").Replace("\ \ \"} \ ""."");
            //ticket = JsonHelper.StringToObject<TicketModel>(response.Content.ReadAsStringAsync().Result).Ticket;}} {string url = "http://localhost:8088/api/users/GetUserByName? username=superman";
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Timeout = 30 * 1000;
        request.Headers.Add(HttpRequestHeader.Authorization, "BasicAuth " + ticket);// Add Authorization to header files
        //request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36";
        //request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
        string result = "";
        using (var res = request.GetResponse() as HttpWebResponse)
        {
            if (res.StatusCode == HttpStatusCode.OK)
            {
                StreamReader reader = newStreamReader(res.GetResponseStream(), Encoding.UTF8); result = reader.ReadToEnd(); }}} {string url = "http://localhost:8088/api/users/GetUserByName? username=superman";
        var handler = new HttpClientHandler();

        using (var http = new HttpClient(handler))
        {
            http.DefaultRequestHeaders.Add("Authorization"."BasicAuth " + ticket);// Add Authorization to header files
            var response = http.GetAsync(url).Result;
            Console.WriteLine(response.StatusCode);
            stringresult = response.Content.ReadAsStringAsync().Result; }}}#endregion
Copy the code

Permission check feature and skip check feature

public class CustomBasicAuthorizeAttribute : AuthorizeAttribute
{
   /// <summary>
   ///Check permissions before action
   /// </summary>
   /// <param name="actionContext"></param>
   public override void OnAuthorization(HttpActionContext actionContext)
   {
       //actionContext.Request.Headers["Authorization"]
       if(actionContext.ActionDescriptor.GetCustomAttributes<CustomAllowAnonymousAttribute>().FirstOrDefault() ! =null)
       {
           return;/ / to continue
       }
       else if(actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<CustomAllowAnonymousAttribute>().FirstOrDefault ()! =null)
       {
           return;/ / to continue
       }
       else
       {
           var authorization = actionContext.Request.Headers.Authorization;
           if (authorization == null)
           {
               this.HandlerUnAuthorization();
           }
           else if (this.ValidateTicket(authorization.Parameter))
           {
               return;/ / to continue
           }
           else
           {
               this.HandlerUnAuthorization(); }}}private void HandlerUnAuthorization()
   {
       throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
   }
   private bool ValidateTicket(string encryptTicket){decrypts the Ticket//if (string.IsNullOrWhiteSpace(encryptTicket))
       // return false;
       try
       {
           var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;
           //FormsAuthentication.Decrypt(encryptTicket).
           return string.Equals(strTicket, string.Format("{0} and {1}"."Admin"."123456"));// It should be split and verified by the database
       }
       catch (Exception ex)
       {
           return false; }}}Copy the code
public class CustomAllowAnonymousAttribute : Attribute{}Copy the code

Controller and method registrations for permissions are not mentioned, but global registrations

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.DependencyResolver = new UnityDependencyResolver(ContainerFactory.BuildContainer());

        //config.Filters.Add(new CustomBasicAuthorizeAttribute()); // Global registration
        config.Filters.Add(new CustomExceptionFilterAttribute());

        config.Services.Replace(typeof(IExceptionHandler), new CustomExceptionHandler());// Replace the global exception handling class

        //config.EnableCors(new EnableCorsAttribute("*", "*", "*")); // All allowed,

        // Web API routing
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
         name: "CustomApi".// The default API route
         routeTemplate: "api/{controller}/{action}/{id}".// Regular rules, starting with API, the second controller and the third parameter
         defaults: new { id = RouteParameter.Optional }
     );


        config.Routes.MapHttpRoute(
            name: "DefaultApi".// The default API route
            routeTemplate: "api/{controller}/{id}".// Regular rules, starting with API, the second controller and the third parameter
            defaults: new{ id = RouteParameter.Optional } ); }}Copy the code