• webapi 权限控制解决方案


    随着移动互联网的发展,webapi的应用越来越广泛,本文是笔者总结的webapi的认证校验案例,欢迎指出

    案例分为两个功能:

      1、用户登录,传入账号和密码到api服务器,然后服务器使用FormsAuthenticationTicket作为身份令牌处理

      2、正式操作数据,传入登录是服务器返回的令牌数据到api服务器,服务器对令牌进行校验返回结果信息

    FormsAuthenticationTicket是微软提供给我们开发人员使用,做身份认证使用的,通过认证,我们可以把关键信息存储到服务器。

    具体案例

      一、api.html页面,用于测试调用api接口

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8" />
     5     <title></title>
     6     <script src="Scripts/jquery-1.10.2.min.js"></script>
     7     <script>
     8         function Login() {
     9             alert("数据获取中")
    10             $.ajax({
    11                 cache: true,
    12                 type: "POST",
    13                 url: "/api/Account/Login",
    14                 data: $('#formLogin').serialize(),// 你的formid
    15                 async: false,
    16                 beforeSend: function (request) {
    17                     request.setRequestHeader("token", $("#token").val());
    18                 },
    19                 error: function (request) {
    20                     alert("Connection error");
    21                 },
    22                 success: function (data) {
    23                     alert("数据获取成功" + data["token"])
    24                     $("#token").val(data["token"]);
    25 
    26                     alert($("#token").val())
    27                 }
    28             });
    29         }
    30         function Work() {
    31             alert("数据获取中")
    32             alert($("#token").val());
    33             $.ajax({
    34                 cache: true,
    35                 type: "POST",
    36                 url: "/api/Work/GetData",
    37                 data: $('#formWork').serialize(),// 你的formid
    38                 async: false,
    39                 beforeSend: function (request) {
    40                     request.setRequestHeader("token", $("#token").val());
    41                 },
    42                 error: function (request) {
    43                     alert(" ");
    44                 },
    45                 success: function (data) {
    46                     alert("数据获取成功")
    47                     alert(data["state"])
    48                 }
    49             });
    50 
    51 
    52         }
    53     </script>
    54 </head>
    55 <body>
    56     <div id="token"></div>
    57     登录测试(Account)
    58     <form id="formLogin" method="post">
    59         <table>
    60             <tr><td> loginName: </td><td><input type="text" name="loginName" /></td></tr>
    61             <tr><td>password:</td><td><input type="text" name="password" /></td></tr>
    62         </table>
    63         <input type="button" onclick="Login()" value="登录" />
    64     </form>
    65     登录测试(Account)
    66     <form id="formWork" method="post">
    67         <table>
    68             <tr><td> loginName: </td><td><input type="text" name="loginName" /></td></tr>
    69           
    70         </table>
    71         <input type="button" onclick="Work()" value="登录" />
    72     </form>
    73 </body>
    74 </html>

    二、登录控制器

      

     1 namespace _01WebApi.Controllers
     2 {
     3     public class AccountController : ApiController
     4     {
     5         [AcceptVerbs("POST", "GET")]
     6         public HttpResponseMessage Login([FromBody]GetDataModel getData)
     7         {
     8             HttpResponseMessage result;
     9             string returnValue = "";
    10             try
    11             { 
    12                 //生成票据
    13                 string loginName =getData.loginName;
    14                 string password = getData.password;
    15                 FormsAuthenticationTicket token = new FormsAuthenticationTicket(0, loginName, DateTime.Now,
    16                               DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", loginName, password),
    17                               FormsAuthentication.FormsCookiePath);
    18                 //返回登录结果、用户信息、用户验证票据信息
    19                 var Token = FormsAuthentication.Encrypt(token);
    20 
    21 
    22                 File.WriteAllText("d:/loginName" + "_Login.txt", Token);
    23 
    24                 returnValue = "{"token":"" + Token + ""}";
    25 
    26                 result = new HttpResponseMessage { Content = new StringContent(returnValue, Encoding.GetEncoding("UTF-8"), "application/json") };//这里是去掉反斜杠再放回出去,json就只剩下双引号。
    27                 return result;
    28 
    29             }
    30             catch (Exception ex)
    31             {
    32                 returnValue = ex.Message.ToString().Replace("
    ", "").Replace("
    ", "");
    33             }
    34             //这里是去掉反斜杠再放回出去,json就只剩下双引号。
    35             result = new HttpResponseMessage { Content = new StringContent(CreateMessage(0, returnValue), Encoding.GetEncoding("UTF-8"), "application/json") };
    36             return result;
    37         }
    38         /// <summary>
    39         /// 返回参数
    40         /// </summary>
    41         /// <param name="State">状态 0 失败  1 成功</param>
    42         /// <param name="Msg">信息</param>
    43         /// <returns></returns>
    44         public static string CreateMessage(int State, string Msg)
    45         {
    46             string str = "{"state":"" + State + "","msg":"" + Msg + ""}";
    47             return str;
    48         }
    49     }
    50     public class GetDataModel
    51     {
    52 
    53         public string loginName { get; set; }
    54         public string password { get; set; }
    55        
    56 
    57     }
    58 
    59 }

    三、获取数据控制器

     1 namespace _01WebApi.Controllers
     2 {
     3     public class WorkController : ApiController
     4     {
     5         [AcceptVerbs("POST", "GET")]
     6         [SupportFilter]
     7         public HttpResponseMessage GetData([FromBody]GetDataModel getData)
     8         {
     9             HttpResponseMessage result;
    10             string returnValue = "";
    11             try
    12             {
    13                 
    14                 returnValue = "{"state":"获取数据成功"}";
    15 
    16                 result = new HttpResponseMessage { Content = new StringContent(returnValue, Encoding.GetEncoding("UTF-8"), "application/json") };//这里是去掉反斜杠再放回出去,json就只剩下双引号。
    17                 return result;
    18 
    19             }
    20             catch (Exception ex)
    21             {
    22                 returnValue = ex.Message.ToString().Replace("
    ", "").Replace("
    ", "");
    23             }
    24             //这里是去掉反斜杠再放回出去,json就只剩下双引号。
    25             result = new HttpResponseMessage { Content = new StringContent(CreateMessage(0, returnValue), Encoding.GetEncoding("UTF-8"), "application/json") };
    26             return result;
    27         }
    28         /// <summary>
    29         /// 返回参数
    30         /// </summary>
    31         /// <param name="State">状态 0 失败  1 成功</param>
    32         /// <param name="Msg">信息</param>
    33         /// <returns></returns>
    34         public static string CreateMessage(int State, string Msg)
    35         {
    36             string str = "{"state":"" + State + "","msg":"" + Msg + ""}";
    37             return str;
    38         }
    39     }
    40 }

    四、在控制器上增加自定义特性来校验令牌数据

     1 namespace _01WebApi.Common
     2 {
     3     public class SupportFilter : AuthorizeAttribute
     4     {
     5         //重写基类的验证方式,加入我们自定义的Ticket验证
     6         public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
     7 
     8         {
     9             //url获取token
    10             var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
    11             //获取用户提交的token数据,用于和服务器数据进行对比,来判定用户是否有效
    12             string token = content.Request.Headers["token"].ToString();
    13           
    14             if (!string.IsNullOrEmpty(token))
    15             {
    16                 //解密用户ticket,并校验用户名密码是否匹配
    17                 if (ValidateTicket(token))
    18                 {
    19                     base.IsAuthorized(actionContext);
    20                 }
    21                 else
    22                 {
    23                     HandleUnauthorizedRequest(actionContext);
    24                 }
    25             }
    26             //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
    27             else
    28             {
    29                 var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
    30                 bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
    31                 if (isAnonymous) base.OnAuthorization(actionContext);
    32                 else HandleUnauthorizedRequest(actionContext);
    33             }
    34         }
    35 
    36         //校验用户名密码(对Session匹配,或数据库数据匹配)
    37         private bool ValidateTicket(string encryptToken)
    38         {
    39             //解密Ticket,并且获取UserData的值
    40             var strTicket = FormsAuthentication.Decrypt(encryptToken).UserData;
    41 
    42             //从Ticket里面获取用户名和密码
    43             var index = strTicket.IndexOf("&");
    44             string loginName = strTicket.Substring(0, index);
    45             string password = strTicket.Substring(index + 1);
    46         
    47            //获取存储在服务器上面的token数据
    48             string token = File.ReadAllText("d:/loginName" + "_Login.txt");
    49             if (token == null)
    50             {
    51                 return false;
    52             }
    53             //对比服务器中的令牌和传入的是否相等
    54             if (token.ToString() == encryptToken)
    55             {
    56                 return true;
    57             }
    58 
    59             return false;
    60 
    61         }
    62     }
    63 }
  • 相关阅读:
    电商零售数仓建模之平台01:平台业务模型
    js自动补零
    Git
    C# HttpClient 请求认证、数据传输笔记
    悲/乐观并发控制的区别
    Win10安装node.js始终出现2503错误解决方法
    行首和行尾快捷键
    IP地址分类和私有地址
    source面板看不到js的调试方法
    js常用类型判断
  • 原文地址:https://www.cnblogs.com/happygx/p/8633116.html
Copyright © 2020-2023  润新知