精华内容
下载资源
问答
  • webapi token验证例子

    2021-04-09 22:01:15
    webapi token验证例子 webapi token验证例子 webapi token验证例子 webapi token验证例子
  • If I want to use WAP1 from another WebAPI (WAP2) I need to configure another client flow for WAP1? Or I can use the same Implicit client client flow configured? Thanks for the support</p><p>该提问...
  • WebApi实现验证授权Token,WebApi生成文档等 - CSDN博客 原文:WebApi实现验证授权Token,WebApi生成文档等 - CSDN博客 [csharp] view plain copy print?usingSy...
    原文:WebApi实现验证授权Token,WebApi生成文档等 - CSDN博客

    1. using System;  
    2. using System.Linq;  
    3. using System.Web;  
    4. using System.Web.Http;  
    5. using System.Web.Security;  
    6.   
    7. namespace OtherApi.Auth  
    8. {  
    9.   
    10.     public class AuthFilterOutside : AuthorizeAttribute  
    11.     {  
    12.         //重写基类的验证方式,加入我们自定义的Ticket验证  
    13.         public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)  
    14.         {  
    15.             //url获取token  
    16.             var content = actionContext.Request.Properties["MS_HttpContext"as HttpContextBase;  
    17.             var token = content.Request.Headers["Token"];  
    18.             if (!string.IsNullOrEmpty(token))  
    19.             {  
    20.                 //解密用户ticket,并校验用户名密码是否匹配  
    21.                 if (ValidateTicket(token))  
    22.                 {  
    23.                     base.IsAuthorized(actionContext);  
    24.                 }  
    25.                 else  
    26.                 {  
    27.                     HandleUnauthorizedRequest(actionContext);  
    28.                 }  
    29.             }  
    30.             //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401  
    31.             else  
    32.             {  
    33.                 var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();  
    34.                 bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);  
    35.                 if (isAnonymous) base.OnAuthorization(actionContext);  
    36.                 else HandleUnauthorizedRequest(actionContext);  
    37.             }  
    38.         }  
    39.   
    40.         //校验票据(数据库数据匹配)  
    41.         private bool ValidateTicket(string encryptToken)  
    42.         {  
    43.             bool flag = false;  
    44.             try  
    45.             {  
    46.                 //获取数据库Token  
    47.                 Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);  
    48.                 if (model.Token == encryptToken) //存在  
    49.                 {  
    50.                     //未超时  
    51.                     flag = (DateTime.Now <= model.ExpireDate) ? true : false;  
    52.                 }  
    53.             }  
    54.             catch (Exception ex) { }  
    55.             return flag;  
    56.         }  
    57.     }  
    58. }  
    using System;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Security;
    
    namespace OtherApi.Auth
    {
    
        public class AuthFilterOutside : AuthorizeAttribute
        {
            //重写基类的验证方式,加入我们自定义的Ticket验证
            public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                //url获取token
                var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
                var token = content.Request.Headers["Token"];
                if (!string.IsNullOrEmpty(token))
                {
                    //解密用户ticket,并校验用户名密码是否匹配
                    if (ValidateTicket(token))
                    {
                        base.IsAuthorized(actionContext);
                    }
                    else
                    {
                        HandleUnauthorizedRequest(actionContext);
                    }
                }
                //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
                else
                {
                    var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                    bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                    if (isAnonymous) base.OnAuthorization(actionContext);
                    else HandleUnauthorizedRequest(actionContext);
                }
            }
    
            //校验票据(数据库数据匹配)
            private bool ValidateTicket(string encryptToken)
            {
                bool flag = false;
                try
                {
                    //获取数据库Token
                    Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);
                    if (model.Token == encryptToken) //存在
                    {
                        //未超时
                        flag = (DateTime.Now <= model.ExpireDate) ? true : false;
                    }
                }
                catch (Exception ex) { }
                return flag;
            }
        }
    }

    1. using System;  
    2. using System.Web;  
    3. using System.Web.Http;  
    4. using System.Web.Security;  
    5. using System.Net.Http;  
    6. using System.Collections.Generic;  
    7. using Newtonsoft.Json;  
    8. using Newtonsoft.Json.Linq;  
    9. using System.Text;  
    10. using OtherApi.Auth;  //引用验证  
    11.   
    12. namespace SpiderApi.Controllers  
    13. {  
    14.     /// <summary>  
    15.     /// 用户授权接口  
    16.     /// </summary>  
    17.     public class AccountController : ApiController  
    18.     {  
    19.         #region 用户登录授权  
    20.         /// <summary>  
    21.         /// 用户登录授权  
    22.         /// </summary>  
    23.         /// <param name="username">用户名</param>  
    24.         /// <param name="password">密码</param>  
    25.         /// <returns></returns>  
    26.         [Route("api/account/login")]  
    27.         [HttpGet]  
    28.         public HttpResponseMessage Login(string username, string password)  
    29.         {  
    30.             //定义  
    31.             ResponseResult obj = new ResponseResult();  
    32.             var model = GetLoginModel(username, password);  
    33.             if (model != null)  
    34.             {  
    35.                 int userId = model.UserId;  
    36.                 string Token = UntilHelper.Md5Encode(UntilHelper.GetExtGuidID(), 32);  
    37.                 var dtNow = DateTime.Now;  
    38.  
    39.                 #region 将身份信息保存票据表中,验证当前请求是否是有效请求  
    40.                 //判断此用户是否存在票据信息  
    41.                 if (Dec.BLL.TicketAuth.GetTicketAuthByUserId(userId) != null)  
    42.                 {  
    43.                     //清空重置  
    44.                     Dec.BLL.TicketAuth.DeleteByUserId(userId);  
    45.                 }  
    46.                 Dec.Models.TicketAuth ticket = new Dec.Models.TicketAuth();  
    47.                 ticket.UserID = userId;  
    48.                 ticket.Token = Token;  
    49.                 ticket.CreateDate = dtNow;  
    50.                 ticket.ExpireDate = dtNow.AddMinutes(30); //30分钟过期  
    51.                 Dec.BLL.TicketAuth.Add(ticket);  
    52.                 #endregion  
    53.   
    54.                 //返回信息              
    55.                 obj.status = true;  
    56.                 obj.message = "用户登录成功";  
    57.                 JObject jo = new JObject();  
    58.                 jo.Add("userid", userId);  
    59.                 jo.Add("loginname", model.LoginName);  
    60.                 jo.Add("nickname", model.NickName);  
    61.                 jo.Add("usertype", model.UserType); //(int)UserTypeEnum.Seller  
    62.                 jo.Add("token", Token);  
    63.                 obj.info = jo;  
    64.             }  
    65.             else  
    66.             {  
    67.                 obj.status = false;  
    68.                 obj.message = "用户登录失败";  
    69.             }  
    70.             var resultObj = JsonConvert.SerializeObject(obj, Formatting.Indented);  
    71.             HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };  
    72.             return result;  
    73.         }  
    74.         #endregion  
    75.  
    76.         #region 用户退出登录,清空Token  
    77.         /// <summary>  
    78.         /// 用户退出登录,清空Token  
    79.         /// </summary>  
    80.         /// <param name="userId">用户ID</param>  
    81.         /// <returns></returns>  
    82.         [Route("api/account/loginout")]  
    83.         [HttpGet]  
    84.         public HttpResponseMessage LoginOut(int userId)  
    85.         {  
    86.             //定义  
    87.             ResponseResult obj = new ResponseResult();  
    88.             try  
    89.             {  
    90.                 //清空数据库该用户票据数据  
    91.                 Dec.BLL.TicketAuth.DeleteByUserId(userId);  
    92.             }  
    93.             catch (Exception ex) { }  
    94.             //返回信息              
    95.             obj.status = true;  
    96.             obj.message = "成功退出";  
    97.             var resultObj = JsonConvert.SerializeObject(obj);  
    98.             HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };  
    99.             return result;  
    100.         }  
    101.         #endregion  
    102.  
    103.         #region 查询Token是否有效  
    104.         /// <summary>  
    105.         /// 查询Token是否有效  
    106.         /// </summary>  
    107.         /// <param name="token">token</param>  
    108.         /// <returns></returns>  
    109.         [Route("api/account/validatetoken")]  
    110.         [HttpGet]  
    111.         public HttpResponseMessage ValidateToken(string token)  
    112.         {  
    113.             //定义  
    114.             ResponseResult obj = new ResponseResult();  
    115.             bool flag = ValidateTicket(token);  
    116.             if (flag)  
    117.             {  
    118.                 //返回信息              
    119.                 obj.status = true;  
    120.                 obj.message = "token有效";  
    121.             }  
    122.             else  
    123.             {  
    124.                 obj.status = false;  
    125.                 obj.message = "token无效";  
    126.             }  
    127.             var resultObj = JsonConvert.SerializeObject(obj);  
    128.             HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };  
    129.             return result;  
    130.         }  
    131.         #endregion  
    132.  
    133.         #region 获取用户账户余额  
    134.         /// <summary>  
    135.         /// 获取用户账户余额  
    136.         /// </summary>  
    137.         /// <param name="userId">用户ID</param>  
    138.         /// <returns></returns>  
    139.         [Route("api/account/amount")]  
    140.         [HttpGet]  
    141.         [AuthFilterOutside] //添加验证  
    142.         public HttpResponseMessage GetAmount(int userId)  
    143.         {  
    144.             //定义  
    145.             ResponseResult obj = new ResponseResult();  
    146.             //获取数据库数据  
    147.             Dec.Models.UserInfo model = Dec.BLL.UserInfo.GetUserInfoByUserId(userId);  
    148.             if (model != null)  
    149.             {  
    150.                 //返回信息              
    151.                 obj.status = true;  
    152.                 obj.message = "获取用户账户余额成功";  
    153.                 JObject jo = new JObject();  
    154.                 jo.Add("userid", model.UserId);  
    155.                 jo.Add("amount", model.Amount);  
    156.                 obj.info = jo;  
    157.             }  
    158.             else  
    159.             {  
    160.                 obj.status = false;  
    161.                 obj.message = "获取用户账户余额失败";  
    162.             }  
    163.   
    164.             var resultObj = JsonConvert.SerializeObject(obj);  
    165.             HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };  
    166.             return result;  
    167.         }  
    168.         #endregion  
    169.   
    170.         /// <summary>  
    171.         /// 用户充值接口  
    172.         /// </summary>  
    173.         /// <param name="userid">用户ID</param>  
    174.         /// <param name="amount">充值金额</param>  
    175.         /// <returns></returns>  
    176.         [Route("api/account/recharge")]  
    177.         [HttpGet]  
    178.         [AuthFilterInside]  
    179.         public HttpResponseMessage Recharge(string userid, double amount)  
    180.         {  
    181.             //定义  
    182.             ResponseResult obj = new ResponseResult();  
    183.             //获取数据库数据  
    184.   
    185.             //返回信息              
    186.             obj.status = true;  
    187.             obj.message = "操作成功,请等待第三方支付平台返回通知核实是否到账";  
    188.             JObject jo = new JObject();  
    189.             jo.Add("userid""123456789");  
    190.             jo.Add("amount", 125.80);  
    191.             obj.info = jo;  
    192.   
    193.             var resultObj = JsonConvert.SerializeObject(obj);  
    194.             HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };  
    195.             return result;  
    196.         }  
    197.  
    198.          #region 验证票据是否有效  
    199.         /// <summary>  
    200.         /// 验证票据是否有效  
    201.         /// </summary>  
    202.         /// <param name="encryptToken">token</param>  
    203.         /// <returns></returns>  
    204.         private bool ValidateTicket(string encryptToken)  
    205.         {  
    206.             bool flag = false;  
    207.             try  
    208.             {  
    209.                 //获取数据库Token  
    210.                 Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);  
    211.                 if (model.Token == encryptToken) //存在  
    212.                 {  
    213.                     //未超时  
    214.                     flag = (DateTime.Now <= model.ExpireDate) ? true : false;  
    215.                 }  
    216.             }  
    217.             catch (Exception ex) { }  
    218.             return flag;  
    219.         }  
    220.         #endregion  
    221.  
    222.         #region 用户登录  
    223.         /// <summary>  
    224.         /// 用户登录  
    225.         /// </summary>  
    226.         /// <param name="userName">用户名</param>  
    227.         /// <param name="userPwd">密码</param>  
    228.         /// <returns></returns>  
    229.         private Dec.Models.UserInfo GetLoginModel(string userName, string userPwd)  
    230.         {  
    231.             Dec.Models.UserInfo model = new Dec.Models.UserInfo();  
    232.             try  
    233.             {  
    234.                 if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(userPwd))  
    235.                 {  
    236.                     //数据库比对  
    237.                     model = Dec.BLL.UserInfo.GetUserInfoByUserNamePwd(userName, UntilHelper.Md5Encode(userPwd, 32));  
    238.                 }  
    239.             }  
    240.             catch (Exception ex) { }  
    241.             return model;  
    242.         }  
    243.         #endregion  
    244.     }  
    245. }  
    using System;
    using System.Web;
    using System.Web.Http;
    using System.Web.Security;
    using System.Net.Http;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System.Text;
    using OtherApi.Auth;  //引用验证
    
    namespace SpiderApi.Controllers
    {
        /// <summary>
        /// 用户授权接口
        /// </summary>
        public class AccountController : ApiController
        {
            #region 用户登录授权
            /// <summary>
            /// 用户登录授权
            /// </summary>
            /// <param name="username">用户名</param>
            /// <param name="password">密码</param>
            /// <returns></returns>
            [Route("api/account/login")]
            [HttpGet]
            public HttpResponseMessage Login(string username, string password)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                var model = GetLoginModel(username, password);
                if (model != null)
                {
                    int userId = model.UserId;
                    string Token = UntilHelper.Md5Encode(UntilHelper.GetExtGuidID(), 32);
                    var dtNow = DateTime.Now;
    
                    #region 将身份信息保存票据表中,验证当前请求是否是有效请求
                    //判断此用户是否存在票据信息
                    if (Dec.BLL.TicketAuth.GetTicketAuthByUserId(userId) != null)
                    {
                        //清空重置
                        Dec.BLL.TicketAuth.DeleteByUserId(userId);
                    }
                    Dec.Models.TicketAuth ticket = new Dec.Models.TicketAuth();
                    ticket.UserID = userId;
                    ticket.Token = Token;
                    ticket.CreateDate = dtNow;
                    ticket.ExpireDate = dtNow.AddMinutes(30); //30分钟过期
                    Dec.BLL.TicketAuth.Add(ticket);
                    #endregion
    
                    //返回信息            
                    obj.status = true;
                    obj.message = "用户登录成功";
                    JObject jo = new JObject();
                    jo.Add("userid", userId);
                    jo.Add("loginname", model.LoginName);
                    jo.Add("nickname", model.NickName);
                    jo.Add("usertype", model.UserType); //(int)UserTypeEnum.Seller
                    jo.Add("token", Token);
                    obj.info = jo;
                }
                else
                {
                    obj.status = false;
                    obj.message = "用户登录失败";
                }
                var resultObj = JsonConvert.SerializeObject(obj, Formatting.Indented);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            #region 用户退出登录,清空Token
            /// <summary>
            /// 用户退出登录,清空Token
            /// </summary>
            /// <param name="userId">用户ID</param>
            /// <returns></returns>
            [Route("api/account/loginout")]
            [HttpGet]
            public HttpResponseMessage LoginOut(int userId)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                try
                {
                    //清空数据库该用户票据数据
                    Dec.BLL.TicketAuth.DeleteByUserId(userId);
                }
                catch (Exception ex) { }
                //返回信息            
                obj.status = true;
                obj.message = "成功退出";
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            #region 查询Token是否有效
            /// <summary>
            /// 查询Token是否有效
            /// </summary>
            /// <param name="token">token</param>
            /// <returns></returns>
            [Route("api/account/validatetoken")]
            [HttpGet]
            public HttpResponseMessage ValidateToken(string token)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                bool flag = ValidateTicket(token);
                if (flag)
                {
                    //返回信息            
                    obj.status = true;
                    obj.message = "token有效";
                }
                else
                {
                    obj.status = false;
                    obj.message = "token无效";
                }
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            #region 获取用户账户余额
            /// <summary>
            /// 获取用户账户余额
            /// </summary>
            /// <param name="userId">用户ID</param>
            /// <returns></returns>
            [Route("api/account/amount")]
            [HttpGet]
            [AuthFilterOutside] //添加验证
            public HttpResponseMessage GetAmount(int userId)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                //获取数据库数据
                Dec.Models.UserInfo model = Dec.BLL.UserInfo.GetUserInfoByUserId(userId);
                if (model != null)
                {
                    //返回信息            
                    obj.status = true;
                    obj.message = "获取用户账户余额成功";
                    JObject jo = new JObject();
                    jo.Add("userid", model.UserId);
                    jo.Add("amount", model.Amount);
                    obj.info = jo;
                }
                else
                {
                    obj.status = false;
                    obj.message = "获取用户账户余额失败";
                }
    
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            /// <summary>
            /// 用户充值接口
            /// </summary>
            /// <param name="userid">用户ID</param>
            /// <param name="amount">充值金额</param>
            /// <returns></returns>
            [Route("api/account/recharge")]
            [HttpGet]
            [AuthFilterInside]
            public HttpResponseMessage Recharge(string userid, double amount)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                //获取数据库数据
    
                //返回信息            
                obj.status = true;
                obj.message = "操作成功,请等待第三方支付平台返回通知核实是否到账";
                JObject jo = new JObject();
                jo.Add("userid", "123456789");
                jo.Add("amount", 125.80);
                obj.info = jo;
    
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
    
             #region 验证票据是否有效
            /// <summary>
            /// 验证票据是否有效
            /// </summary>
            /// <param name="encryptToken">token</param>
            /// <returns></returns>
            private bool ValidateTicket(string encryptToken)
            {
                bool flag = false;
                try
                {
                    //获取数据库Token
                    Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);
                    if (model.Token == encryptToken) //存在
                    {
                        //未超时
                        flag = (DateTime.Now <= model.ExpireDate) ? true : false;
                    }
                }
                catch (Exception ex) { }
                return flag;
            }
            #endregion
    
            #region 用户登录
            /// <summary>
            /// 用户登录
            /// </summary>
            /// <param name="userName">用户名</param>
            /// <param name="userPwd">密码</param>
            /// <returns></returns>
            private Dec.Models.UserInfo GetLoginModel(string userName, string userPwd)
            {
                Dec.Models.UserInfo model = new Dec.Models.UserInfo();
                try
                {
                    if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(userPwd))
                    {
                        //数据库比对
                        model = Dec.BLL.UserInfo.GetUserInfoByUserNamePwd(userName, UntilHelper.Md5Encode(userPwd, 32));
                    }
                }
                catch (Exception ex) { }
                return model;
            }
            #endregion
        }
    }
    
    1. //  
    2. using System;  
    3. using System.Collections.Generic;  
    4. using System.Linq;  
    5. using System.Web;  
    6. using System.Web.Http;  
    7. using System.Web.Mvc;  
    8. using System.Web.Routing;  
    9.   
    10. namespace SpiderApi  
    11. {  
    12.     public class WebApiApplication : System.Web.HttpApplication  
    13.     {  
    14.         protected void Application_Start()  
    15.         {  
    16.             //WebApi文档  
    17.             AreaRegistration.RegisterAllAreas();  
    18.             GlobalConfiguration.Configure(WebApiConfig.Register);  
    19.         }  
    20.   
    21.         protected void Application_PostAuthorizeRequest()  
    22.         {  
    23.             //Enable Session  
    24.             HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);  
    25.         }  
    26.     }  
    27. }  
    //
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace SpiderApi
    {
        public class WebApiApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                //WebApi文档
                AreaRegistration.RegisterAllAreas();
                GlobalConfiguration.Configure(WebApiConfig.Register);
            }
    
            protected void Application_PostAuthorizeRequest()
            {
                //Enable Session
                HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
            }
        }
    }
    
    1. // Uncomment the following to provide samples for PageResult<T>. Must also add the Microsoft.AspNet.WebApi.OData  
    2. // package to your project. 先安装Help Page包  HelpPage=>App_start=>HelpPageConfig.cs  
    3. #define Handle_PageResultOfT  
    4.   
    5. using System;  
    6. using System.Collections;  
    7. using System.Collections.Generic;  
    8. using System.Diagnostics;  
    9. using System.Diagnostics.CodeAnalysis;  
    10. using System.Linq;  
    11. using System.Net.Http.Headers;  
    12. using System.Reflection;  
    13. using System.Web;  
    14. using System.Web.Http;  
    15. using SpiderApi.Models;  
    16. #if Handle_PageResultOfT  
    17. using System.Web.Http.OData;  
    18. #endif  
    19.   
    20. namespace SpiderApi.Areas.HelpPage  
    21. {  
    22.     /// <summary>  
    23.     /// Use this class to customize the Help Page.  
    24.     /// For example you can set a custom <see cref="System.Web.Http.Description.IDocumentationProvider"/> to supply the documentation  
    25.     /// or you can provide the samples for the requests/responses.  
    26.     /// </summary>  
    27.     public static class HelpPageConfig  
    28.     {  
    29.         [SuppressMessage("Microsoft.Globalization""CA1303:Do not pass literals as localized parameters",  
    30.             MessageId = "SpiderApi.Areas.HelpPage.TextSample.#ctor(System.String)",  
    31.             Justification = "End users may choose to merge this string with existing localized resources.")]  
    32.         [SuppressMessage("Microsoft.Naming""CA2204:Literals should be spelled correctly",  
    33.             MessageId = "bsonspec",  
    34.             Justification = "Part of a URI.")]  
    35.         public static void Register(HttpConfiguration config)  
    36.         {  
    37.              Uncomment the following to use the documentation from XML documentation file.  
    38.             //开启解析  
    39.             config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/Bin/SpiderApi.XML")));  
    40.   
    41.              Uncomment the following to use "sample string" as the sample for all actions that have string as the body parameter or return type.  
    42.              Also, the string arrays will be used for IEnumerable<string>. The sample objects will be serialized into different media type   
    43.              formats by the available formatters.  
    44.             //config.SetSampleObjects(new Dictionary<Type, object>  
    45.             //{  
    46.             //    {typeof(string), "sample string"},  
    47.             //    {typeof(IEnumerable<string>), new string[]{"sample 1", "sample 2"}}  
    48.             //});  
    49.             //添加映射  
    50.             config.SetSampleResponse(Sample.BatchSendMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue""BatchSendMessage");  
    51.             config.SetSampleResponse(Sample.BatchReceiveMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue""BatchReceiveMessage");  
    52.             config.SetSampleResponse(Sample.DeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue""DeleteMessage");  
    53.             config.SetSampleResponse(Sample.BatchDeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue""BatchDeleteMessage");  
    54.             config.SetSampleResponse(Sample.ChangeMessageVisibilityResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue""ChangeMessageVisibility");  
    55.   
    56.             // Extend the following to provide factories for types not handled automatically (those lacking parameterless  
    57.             // constructors) or for which you prefer to use non-default property values. Line below provides a fallback  
    58.             // since automatic handling will fail and GeneratePageResult handles only a single type.  
    59. #if Handle_PageResultOfT  
    60.             config.GetHelpPageSampleGenerator().SampleObjectFactories.Add(GeneratePageResult);  
    61. #endif  
    62.   
    63.             // Extend the following to use a preset object directly as the sample for all actions that support a media  
    64.             // type, regardless of the body parameter or return type. The lines below avoid display of binary content.  
    65.             // The BsonMediaTypeFormatter (if available) is not used to serialize the TextSample object.  
    66.             config.SetSampleForMediaType(  
    67.                 new TextSample("Binary JSON content. See http://bsonspec.org for details."),  
    68.                 new MediaTypeHeaderValue("application/bson"));  
    69.   
    70.              Uncomment the following to use "[0]=foo&[1]=bar" directly as the sample for all actions that support form URL encoded format  
    71.              and have IEnumerable<string> as the body parameter or return type.  
    72.             //config.SetSampleForType("[0]=foo&[1]=bar", new MediaTypeHeaderValue("application/x-www-form-urlencoded"), typeof(IEnumerable<string>));  
    73.   
    74.              Uncomment the following to use "1234" directly as the request sample for media type "text/plain" on the controller named "Values"  
    75.              and action named "Put".  
    76.             //config.SetSampleRequest("1234", new MediaTypeHeaderValue("text/plain"), "Values", "Put");  
    77.   
    78.              Uncomment the following to use the image on "../images/aspNetHome.png" directly as the response sample for media type "image/png"  
    79.              on the controller named "Values" and action named "Get" with parameter "id".  
    80.             //config.SetSampleResponse(new ImageSample("../images/aspNetHome.png"), new MediaTypeHeaderValue("image/png"), "Values", "Get", "id");  
    81.   
    82.              Uncomment the following to correct the sample request when the action expects an HttpRequestMessage with ObjectContent<string>.  
    83.              The sample will be generated as if the controller named "Values" and action named "Get" were having string as the body parameter.  
    84.             //config.SetActualRequestType(typeof(string), "Values", "Get");  
    85.   
    86.              Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent<string>.  
    87.              The sample will be generated as if the controller named "Values" and action named "Post" were returning a string.  
    88.             //config.SetActualResponseType(typeof(string), "Values", "Post");  
    89.         }  
    90.  
    91. #if Handle_PageResultOfT  
    92.         private static object GeneratePageResult(HelpPageSampleGenerator sampleGenerator, Type type)  
    93.         {  
    94.             if (type.IsGenericType)  
    95.             {  
    96.                 Type openGenericType = type.GetGenericTypeDefinition();  
    97.                 if (openGenericType == typeof(PageResult<>))  
    98.                 {  
    99.                     // Get the T in PageResult<T>  
    100.                     Type[] typeParameters = type.GetGenericArguments();  
    101.                     Debug.Assert(typeParameters.Length == 1);  
    102.   
    103.                     // Create an enumeration to pass as the first parameter to the PageResult<T> constuctor  
    104.                     Type itemsType = typeof(List<>).MakeGenericType(typeParameters);  
    105.                     object items = sampleGenerator.GetSampleObject(itemsType);  
    106.   
    107.                     // Fill in the other information needed to invoke the PageResult<T> constuctor  
    108.                     Type[] parameterTypes = new Type[] { itemsType, typeof(Uri), typeof(long?), };  
    109.                     object[] parameters = new object[] { items, null, (long)ObjectGenerator.DefaultCollectionSize, };  
    110.   
    111.                     // Call PageResult(IEnumerable<T> items, Uri nextPageLink, long? count) constructor  
    112.                     ConstructorInfo constructor = type.GetConstructor(parameterTypes);  
    113.                     return constructor.Invoke(parameters);  
    114.                 }  
    115.             }  
    116.   
    117.             return null;  
    118.         }  
    119. #endif  
    120.     }  
    121. }  
    // Uncomment the following to provide samples for PageResult<T>. Must also add the Microsoft.AspNet.WebApi.OData
    // package to your project. 先安装Help Page包  HelpPage=>App_start=>HelpPageConfig.cs
    #define Handle_PageResultOfT
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Net.Http.Headers;
    using System.Reflection;
    using System.Web;
    using System.Web.Http;
    using SpiderApi.Models;
    #if Handle_PageResultOfT
    using System.Web.Http.OData;
    #endif
    
    namespace SpiderApi.Areas.HelpPage
    {
        /// <summary>
        /// Use this class to customize the Help Page.
        /// For example you can set a custom <see cref="System.Web.Http.Description.IDocumentationProvider"/> to supply the documentation
        /// or you can provide the samples for the requests/responses.
        /// </summary>
        public static class HelpPageConfig
        {
            [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
                MessageId = "SpiderApi.Areas.HelpPage.TextSample.#ctor(System.String)",
                Justification = "End users may choose to merge this string with existing localized resources.")]
            [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly",
                MessageId = "bsonspec",
                Justification = "Part of a URI.")]
            public static void Register(HttpConfiguration config)
            {
                 Uncomment the following to use the documentation from XML documentation file.
                //开启解析
                config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/Bin/SpiderApi.XML")));
    
                 Uncomment the following to use "sample string" as the sample for all actions that have string as the body parameter or return type.
                 Also, the string arrays will be used for IEnumerable<string>. The sample objects will be serialized into different media type 
                 formats by the available formatters.
                //config.SetSampleObjects(new Dictionary<Type, object>
                //{
                //    {typeof(string), "sample string"},
                //    {typeof(IEnumerable<string>), new string[]{"sample 1", "sample 2"}}
                //});
                //添加映射
                config.SetSampleResponse(Sample.BatchSendMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchSendMessage");
                config.SetSampleResponse(Sample.BatchReceiveMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchReceiveMessage");
                config.SetSampleResponse(Sample.DeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "DeleteMessage");
                config.SetSampleResponse(Sample.BatchDeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchDeleteMessage");
                config.SetSampleResponse(Sample.ChangeMessageVisibilityResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "ChangeMessageVisibility");
    
                // Extend the following to provide factories for types not handled automatically (those lacking parameterless
                // constructors) or for which you prefer to use non-default property values. Line below provides a fallback
                // since automatic handling will fail and GeneratePageResult handles only a single type.
    #if Handle_PageResultOfT
                config.GetHelpPageSampleGenerator().SampleObjectFactories.Add(GeneratePageResult);
    #endif
    
                // Extend the following to use a preset object directly as the sample for all actions that support a media
                // type, regardless of the body parameter or return type. The lines below avoid display of binary content.
                // The BsonMediaTypeFormatter (if available) is not used to serialize the TextSample object.
                config.SetSampleForMediaType(
                    new TextSample("Binary JSON content. See http://bsonspec.org for details."),
                    new MediaTypeHeaderValue("application/bson"));
    
                 Uncomment the following to use "[0]=foo&[1]=bar" directly as the sample for all actions that support form URL encoded format
                 and have IEnumerable<string> as the body parameter or return type.
                //config.SetSampleForType("[0]=foo&[1]=bar", new MediaTypeHeaderValue("application/x-www-form-urlencoded"), typeof(IEnumerable<string>));
    
                 Uncomment the following to use "1234" directly as the request sample for media type "text/plain" on the controller named "Values"
                 and action named "Put".
                //config.SetSampleRequest("1234", new MediaTypeHeaderValue("text/plain"), "Values", "Put");
    
                 Uncomment the following to use the image on "../images/aspNetHome.png" directly as the response sample for media type "image/png"
                 on the controller named "Values" and action named "Get" with parameter "id".
                //config.SetSampleResponse(new ImageSample("../images/aspNetHome.png"), new MediaTypeHeaderValue("image/png"), "Values", "Get", "id");
    
                 Uncomment the following to correct the sample request when the action expects an HttpRequestMessage with ObjectContent<string>.
                 The sample will be generated as if the controller named "Values" and action named "Get" were having string as the body parameter.
                //config.SetActualRequestType(typeof(string), "Values", "Get");
    
                 Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent<string>.
                 The sample will be generated as if the controller named "Values" and action named "Post" were returning a string.
                //config.SetActualResponseType(typeof(string), "Values", "Post");
            }
    
    #if Handle_PageResultOfT
            private static object GeneratePageResult(HelpPageSampleGenerator sampleGenerator, Type type)
            {
                if (type.IsGenericType)
                {
                    Type openGenericType = type.GetGenericTypeDefinition();
                    if (openGenericType == typeof(PageResult<>))
                    {
                        // Get the T in PageResult<T>
                        Type[] typeParameters = type.GetGenericArguments();
                        Debug.Assert(typeParameters.Length == 1);
    
                        // Create an enumeration to pass as the first parameter to the PageResult<T> constuctor
                        Type itemsType = typeof(List<>).MakeGenericType(typeParameters);
                        object items = sampleGenerator.GetSampleObject(itemsType);
    
                        // Fill in the other information needed to invoke the PageResult<T> constuctor
                        Type[] parameterTypes = new Type[] { itemsType, typeof(Uri), typeof(long?), };
                        object[] parameters = new object[] { items, null, (long)ObjectGenerator.DefaultCollectionSize, };
    
                        // Call PageResult(IEnumerable<T> items, Uri nextPageLink, long? count) constructor
                        ConstructorInfo constructor = type.GetConstructor(parameterTypes);
                        return constructor.Invoke(parameters);
                    }
                }
    
                return null;
            }
    #endif
        }
    }
    1. /* 
    2. API接口测试工具 - WebApiTestClient使用--Nuget引入组件  
    3. --A Simple Test Client for ASP.NET Web API 
    4. */  
    5. /* 
    6. 1、修改Api.cshtml文件 
    7. 通过上述步骤,就能将组件WebAPITestClient引入进来。下面我们只需要做一件事:打开文件 (根据 Areas\HelpPage\Views\Help) Api.cshtml 并添加以下内容: 
    8.  
    9. @Html.DisplayForModel("TestClientDialogs") 
    10. @Html.DisplayForModel("TestClientReferences") 
    11. 添加后Api.cshtml文件的代码如下 
    12. */  
    13.   
    14.   
    15. @using System.Web.Http  
    16. @using WebApiTestClient.Areas.HelpPage.Models  
    17. @model HelpPageApiModel  
    18.   
    19. @{  
    20.     var description = Model.ApiDescription;  
    21.     ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath;  
    22. }  
    23.   
    24. <link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />  
    25. <div id="body" class="help-page">  
    26.     <section class="featured">  
    27.         <div class="content-wrapper">  
    28.             <p>  
    29.                 @Html.ActionLink("Help Page Home""Index")  
    30.             </p>  
    31.         </div>  
    32.     </section>  
    33.     <section class="content-wrapper main-content clear-fix">  
    34.         @Html.DisplayForModel()  
    35.     </section>  
    36. </div>  
    37.   
    38. @Html.DisplayForModel("TestClientDialogs")  
    39. @section Scripts{  
    40.     <link href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />  
    41.     @Html.DisplayForModel("TestClientReferences")  
    42. }  
    /*
    API接口测试工具 - WebApiTestClient使用--Nuget引入组件 
    --A Simple Test Client for ASP.NET Web API
    */
    /*
    1、修改Api.cshtml文件
    通过上述步骤,就能将组件WebAPITestClient引入进来。下面我们只需要做一件事:打开文件 (根据 Areas\HelpPage\Views\Help) Api.cshtml 并添加以下内容:
    
    @Html.DisplayForModel("TestClientDialogs")
    @Html.DisplayForModel("TestClientReferences")
    添加后Api.cshtml文件的代码如下
    */
    
    
    @using System.Web.Http
    @using WebApiTestClient.Areas.HelpPage.Models
    @model HelpPageApiModel
    
    @{
        var description = Model.ApiDescription;
        ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath;
    }
    
    <link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
    <div id="body" class="help-page">
        <section class="featured">
            <div class="content-wrapper">
                <p>
                    @Html.ActionLink("Help Page Home", "Index")
                </p>
            </div>
        </section>
        <section class="content-wrapper main-content clear-fix">
            @Html.DisplayForModel()
        </section>
    </div>
    
    @Html.DisplayForModel("TestClientDialogs")
    @section Scripts{
        <link href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
        @Html.DisplayForModel("TestClientReferences")
    }

    posted on 2017-12-03 00:55 NET未来之路 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lonelyxmas/p/7957256.html

    展开全文
  • 首先问大家一个问题,你在写开放的API接口时是如何保证...请求的唯一性(不可复制),防止请求被恶意攻击为了保证数据在通信时的安全性,我们可以采用TOKEN+参数签名的方式来进行相关验证。比如说我们客户端需要查询...

    首先问大家一个问题,你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面临着许多的安全性问题,例如:

    请求来源(身份)是否合法?

    请求参数被篡改?

    请求的唯一性(不可复制),防止请求被恶意攻击

    为了保证数据在通信时的安全性,我们可以采用TOKEN+参数签名的方式来进行相关验证。

    比如说我们客户端需要查询产品信息这个操作来进行分析,客户端点击查询按钮==》调用服务器端api进行查询==》服务器端返回查询结果

    一、不进行验证的方式

    api查询接口:

    客户端调用:http://api.XXX.com/getproduct?id=value1

    如上,这种方式简单粗暴,在浏览器直接输入"http://api.XXX.com/getproduct?id=value1",即可获取产品列表信息了,但是这样的方式会存在很严重的安全性问题,没有进行任何的验证,大家都可以通过这个方法获取到产品列表,导致产品信息泄露。

    那么,如何验证调用者身份呢?如何防止参数被篡改呢?如何保证请求的唯一性? 如何保证请求的唯一性,防止请求被恶意攻击呢?

    二、使用TOKEN+签名认证 保证请求安全性

    token+签名认证的主要原理是:1.做一个认证服务,提供一个认证的webapi,用户先访问它获取对应的token

    2.用户拿着相应的token以及请求的参数和服务器端提供的签名算法计算出签名后再去访问指定的api

    3.服务器端每次接收到请求就获取对应用户的token和请求参数,服务器端再次计算签名和客户端签名做对比,如果验证通过则正常访问相应的api,验证失败则返回具体的失败信息

    具体代码如下 :

    1.用户请求认证服务GetToken,将TOKEN保存在服务器端缓存中,并返回对应的TOKEN到客户端(该请求不需要进行签名认证)

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    public HttpResponseMessage GetToken(string staffId)

    {

    ResultMsg resultMsg = null;

    int id = 0;

    //判断参数是否合法

    if (string.IsNullOrEmpty(staffId) || (!int.TryParse(staffId, out id)))

    {

    resultMsg = new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;

    resultMsg.Info = StatusCodeEnum.ParameterError.GetEnumText();

    resultMsg.Data = "";

    return HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    }

    //插入缓存

    Token token =(Token)HttpRuntime.Cache.Get(id.ToString());

    if (HttpRuntime.Cache.Get(id.ToString()) == null)

    {

    token = new Token();

    token.StaffId = id;

    token.SignToken = Guid.NewGuid();

    token.ExpireTime = DateTime.Now.AddDays(1);

    HttpRuntime.Cache.Insert(token.StaffId.ToString(), token, null, token.ExpireTime, TimeSpan.Zero);

    }

    //返回token信息

    resultMsg =new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.Success;

    resultMsg.Info = "";

    resultMsg.Data = token;

    return HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    2.客户端调用服务器端API,需要对请求进行签名认证,签名方式如下

    (1) get请求:按照请求参数名称将所有请求参数按照字母先后顺序排序得到:keyvaluekeyvalue...keyvalue  字符串如:将arong=1,mrong=2,crong=3 排序为:arong=1, crong=3,mrong=2  然后将参数名和参数值进行拼接得到参数字符串:arong1crong3mrong2。

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    public static Tuple GetQueryString(Dictionary parames)

    {

    // 第一步:把字典按Key的字母顺序排序

    IDictionary sortedParams = new SortedDictionary(parames);

    IEnumerator> dem = sortedParams.GetEnumerator();

    // 第二步:把所有参数名和参数值串在一起

    StringBuilder query = new StringBuilder(""); //签名字符串

    StringBuilder queryStr = new StringBuilder(""); //url参数

    if (parames == null || parames.Count == 0)

    return new Tuple("","");

    while (dem.MoveNext())

    {

    string key = dem.Current.Key;

    string value = dem.Current.Value;

    if (!string.IsNullOrEmpty(key))

    {

    query.Append(key).Append(value);

    queryStr.Append("&").Append(key).Append("=").Append(value);

    }

    }

    return new Tuple(query.ToString(), queryStr.ToString().Substring(1, queryStr.Length - 1));

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    post请求:将请求的参数对象序列化为json格式字符串

    Product product = new Product() { Id = 1, Name = "安慕希", Count = 10, Price = 58.8 };

    var data=JsonConvert.SerializeObject(product);

    (2)在请求头中添加timespan(时间戳),nonce(随机数),staffId(用户Id),signature(签名参数)

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    //加入头信息

    request.Headers.Add("staffid", staffId.ToString()); //当前请求用户StaffId

    request.Headers.Add("timestamp", timeStamp); //发起请求时的时间戳(单位:毫秒)

    request.Headers.Add("nonce", nonce); //发起请求时的时间戳(单位:毫秒)

    request.Headers.Add("signature", GetSignature(timeStamp,nonce,staffId,data)); //当前请求内容的数字签名

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    (3)根据请求参数计算本次请求的签名,用timespan+nonc+staffId+token+data(请求参数字符串)得到signStr签名字符串,然后再进行排序和MD5加密得到最终的signature签名字符串,添加到请求头中

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    private static string GetSignature(string timeStamp,string nonce,int staffId,string data)

    {

    Token token = null;

    var resultMsg = GetSignToken(staffId);

    if (resultMsg != null)

    {

    if (resultMsg.StatusCode == (int)StatusCodeEnum.Success)

    {

    token = resultMsg.Result;

    }

    else

    {

    throw new Exception(resultMsg.Data.ToString());

    }

    }

    else

    {

    throw new Exception("token为null,员工编号为:" +staffId);

    }

    var hash = System.Security.Cryptography.MD5.Create();

    //拼接签名数据

    var signStr = timeStamp +nonce+ staffId + token.SignToken.ToString() + data;

    //将字符串中字符按升序排序

    var sortStr = string.Concat(signStr.OrderBy(c => c));

    var bytes = Encoding.UTF8.GetBytes(sortStr);

    //使用MD5加密

    var md5Val = hash.ComputeHash(bytes);

    //把二进制转化为大写的十六进制

    StringBuilder result = new StringBuilder();

    foreach (var c in md5Val)

    {

    result.Append(c.ToString("X2"));

    }

    return result.ToString().ToUpper();

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    (4) webapi接收到相应的请求,取出请求头中的timespan,nonc,staffid,signature 数据,根据timespan判断此次请求是否失效,根据staffid取出相应token判断token是否失效,根据请求类型取出对应的请求参数,然后服务器端按照同样的规则重新计算请求签名,判断和请求头中的signature数据是否相同,如果相同的话则是合法请求,正常返回数据,如果不相同的话,该请求可能被恶意篡改,禁止访问相应的数据,返回相应的错误信息

    如下使用全局过滤器拦截所有api请求进行统一的处理

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    public class ApiSecurityFilter : ActionFilterAttribute

    {

    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)

    {

    ResultMsg resultMsg = null;

    var request = actionContext.Request;

    string method = request.Method.Method;

    string staffid = String.Empty, timestamp = string.Empty, nonce = string.Empty, signature = string.Empty;

    int id = 0;

    if (request.Headers.Contains("staffid"))

    {

    staffid = HttpUtility.UrlDecode(request.Headers.GetValues("staffid").FirstOrDefault());

    }

    if (request.Headers.Contains("timestamp"))

    {

    timestamp = HttpUtility.UrlDecode(request.Headers.GetValues("timestamp").FirstOrDefault());

    }

    if (request.Headers.Contains("nonce"))

    {

    nonce = HttpUtility.UrlDecode(request.Headers.GetValues("nonce").FirstOrDefault());

    }

    if (request.Headers.Contains("signature"))

    {

    signature = HttpUtility.UrlDecode(request.Headers.GetValues("signature").FirstOrDefault());

    }

    //GetToken方法不需要进行签名验证

    if (actionContext.ActionDescriptor.ActionName == "GetToken")

    {

    if (string.IsNullOrEmpty(staffid) || (!int.TryParse(staffid, out id) || string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(nonce)))

    {

    resultMsg = new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;

    resultMsg.Info = StatusCodeEnum.ParameterError.GetEnumText();

    resultMsg.Data = "";

    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    base.OnActionExecuting(actionContext);

    return;

    }

    else

    {

    base.OnActionExecuting(actionContext);

    return;

    }

    }

    //判断请求头是否包含以下参数

    if (string.IsNullOrEmpty(staffid) || (!int.TryParse(staffid, out id) || string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(nonce) || string.IsNullOrEmpty(signature)))

    {

    resultMsg = new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.ParameterError;

    resultMsg.Info = StatusCodeEnum.ParameterError.GetEnumText();

    resultMsg.Data = "";

    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    base.OnActionExecuting(actionContext);

    return;

    }

    //判断timespan是否有效

    double ts1 = 0;

    double ts2 = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds;

    bool timespanvalidate = double.TryParse(timestamp, out ts1);

    double ts = ts2 - ts1;

    bool falg = ts > int.Parse(WebSettingsConfig.UrlExpireTime) * 1000;

    if (falg || (!timespanvalidate))

    {

    resultMsg = new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.URLExpireError;

    resultMsg.Info = StatusCodeEnum.URLExpireError.GetEnumText();

    resultMsg.Data = "";

    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    base.OnActionExecuting(actionContext);

    return;

    }

    //判断token是否有效

    Token token = (Token)HttpRuntime.Cache.Get(id.ToString());

    string signtoken = string.Empty;

    if (HttpRuntime.Cache.Get(id.ToString()) == null)

    {

    resultMsg = new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.TokenInvalid;

    resultMsg.Info = StatusCodeEnum.TokenInvalid.GetEnumText();

    resultMsg.Data = "";

    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    base.OnActionExecuting(actionContext);

    return;

    }

    else

    {

    signtoken = token.SignToken.ToString();

    }

    //根据请求类型拼接参数

    NameValueCollection form = HttpContext.Current.Request.QueryString;

    string data = string.Empty;

    switch (method)

    {

    case "POST":

    Stream stream = HttpContext.Current.Request.InputStream;

    string responseJson = string.Empty;

    StreamReader streamReader = new StreamReader(stream);

    data = streamReader.ReadToEnd();

    break;

    case "GET":

    //第一步:取出所有get参数

    IDictionary parameters = new Dictionary();

    for (int f = 0; f < form.Count; f++)

    {

    string key = form.Keys[f];

    parameters.Add(key, form[key]);

    }

    // 第二步:把字典按Key的字母顺序排序

    IDictionary sortedParams = new SortedDictionary(parameters);

    IEnumerator> dem = sortedParams.GetEnumerator();

    // 第三步:把所有参数名和参数值串在一起

    StringBuilder query = new StringBuilder();

    while (dem.MoveNext())

    {

    string key = dem.Current.Key;

    string value = dem.Current.Value;

    if (!string.IsNullOrEmpty(key))

    {

    query.Append(key).Append(value);

    }

    }

    data = query.ToString();

    break;

    default:

    resultMsg = new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.HttpMehtodError;

    resultMsg.Info = StatusCodeEnum.HttpMehtodError.GetEnumText();

    resultMsg.Data = "";

    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    base.OnActionExecuting(actionContext);

    return;

    }

    bool result = SignExtension.Validate(timestamp, nonce, id, signtoken,data, signature);

    if (!result)

    {

    resultMsg = new ResultMsg();

    resultMsg.StatusCode = (int)StatusCodeEnum.HttpRequestError;

    resultMsg.Info = StatusCodeEnum.HttpRequestError.GetEnumText();

    resultMsg.Data = "";

    actionContext.Response = HttpResponseExtension.toJson(JsonConvert.SerializeObject(resultMsg));

    base.OnActionExecuting(actionContext);

    return;

    }

    else

    {

    base.OnActionExecuting(actionContext);

    }

    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)

    {

    base.OnActionExecuted(actionExecutedContext);

    }

    }

    48304ba5e6f9fe08f3fa1abda7d326ab.png

    然后我们进行测试,检验api请求的合法性

    Get请求:

    1.获取产品数据,传递参数id=1,name="wahaha"  ,完整请求为http://localhost:14826/api/product/getproduct?id=1&name=wahaha

    a3e63745ad3e9901ea33718aaeec3f48.png

    2.请求头添加timespan,staffid,nonce,signature字段

    8169151b207519cacda7271ff91e32c8.png

    3.如图当data里面的值为id1namewahaha的时候请求头中的signature和服务器端计算出来的result的值是完全一样的,当我将data修改为id1namewahaha1之后,服务器端计算出来的签名result和请求头中提交的signature就不相同了,就表示为不合法的请求了

    df298e523ca1cab54e8695e34cc729a2.png

    4.不合法的请求就会被识别为请求参数已被修改

    eb0ecd3583a0132cf8111ac697ad7545.png

    合法的请求则会返回对应的商品信息

    882528b5cb77c8314db48b93d9a891e4.png

    post请求:

    1.post对象序列化为json字符串后提交到后台,后台返回相应产品信息

    5484f1c69d1fefe6b6e1449eab865e1a.png

    2.后台获取请求的参数信息

    e94dbb586c5e9154ca8994522168aee1.png

    3.判断签名是否成功,第一次请求签名参数signature和服务器端计算result完全相同, 然后当把请求参数中count的数量从10改成100之后服务器端计算的result和请求签名参数signature不同,所以请求不合法,是非法请求,同理如果其他任何参数被修改最后计算的结果都会和签名参数不同,请求同样识别为不合法请求

    c78ac056e55e6eddc153cfb30410378b.png

    总结:

    通过上面的案例,我们可以看出,安全的关键在于参与签名的TOKEN,整个过程中TOKEN是不参与通信的,所以只要保证TOKEN不泄露,请求就不会被伪造。

    然后我们通过timestamp时间戳用来验证请求是否过期,这样就算被人拿走完整的请求链接也是无效的。

    Sign签名的方式能够在一定程度上防止信息被篡改和伪造,保障通信的安全

    源码地址:https://github.com/13138899620/TokenSign

    展开全文
  • using System; using System.Linq; using System.Web; using System.Web.Http;...using System.Web.Security;...namespace OtherApi.Auth { public class AuthFilterOutside : AuthorizeAttribute ...
    using System;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Security;
    
    namespace OtherApi.Auth
    {
    
        public class AuthFilterOutside : AuthorizeAttribute
        {
            //重写基类的验证方式,加入我们自定义的Ticket验证
            public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
            {
                //url获取token
                var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
                var token = content.Request.Headers["Token"];
                if (!string.IsNullOrEmpty(token))
                {
                    //解密用户ticket,并校验用户名密码是否匹配
                    if (ValidateTicket(token))
                    {
                        base.IsAuthorized(actionContext);
                    }
                    else
                    {
                        HandleUnauthorizedRequest(actionContext);
                    }
                }
                //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
                else
                {
                    var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                    bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                    if (isAnonymous) base.OnAuthorization(actionContext);
                    else HandleUnauthorizedRequest(actionContext);
                }
            }
    
            //校验票据(数据库数据匹配)
            private bool ValidateTicket(string encryptToken)
            {
                bool flag = false;
                try
                {
                    //获取数据库Token
                    Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);
                    if (model.Token == encryptToken) //存在
                    {
                        //未超时
                        flag = (DateTime.Now <= model.ExpireDate) ? true : false;
                    }
                }
                catch (Exception ex) { }
                return flag;
            }
        }
    }

     

    using System;
    using System.Web;
    using System.Web.Http;
    using System.Web.Security;
    using System.Net.Http;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System.Text;
    using OtherApi.Auth;  //引用验证
    
    namespace SpiderApi.Controllers
    {
        /// <summary>
        /// 用户授权接口
        /// </summary>
        public class AccountController : ApiController
        {
            #region 用户登录授权
            /// <summary>
            /// 用户登录授权
            /// </summary>
            /// <param name="username">用户名</param>
            /// <param name="password">密码</param>
            /// <returns></returns>
            [Route("api/account/login")]
            [HttpGet]
            public HttpResponseMessage Login(string username, string password)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                var model = GetLoginModel(username, password);
                if (model != null)
                {
                    int userId = model.UserId;
                    string Token = UntilHelper.Md5Encode(UntilHelper.GetExtGuidID(), 32);
                    var dtNow = DateTime.Now;
    
                    #region 将身份信息保存票据表中,验证当前请求是否是有效请求
                    //判断此用户是否存在票据信息
                    if (Dec.BLL.TicketAuth.GetTicketAuthByUserId(userId) != null)
                    {
                        //清空重置
                        Dec.BLL.TicketAuth.DeleteByUserId(userId);
                    }
                    Dec.Models.TicketAuth ticket = new Dec.Models.TicketAuth();
                    ticket.UserID = userId;
                    ticket.Token = Token;
                    ticket.CreateDate = dtNow;
                    ticket.ExpireDate = dtNow.AddMinutes(30); //30分钟过期
                    Dec.BLL.TicketAuth.Add(ticket);
                    #endregion
    
                    //返回信息            
                    obj.status = true;
                    obj.message = "用户登录成功";
                    JObject jo = new JObject();
                    jo.Add("userid", userId);
                    jo.Add("loginname", model.LoginName);
                    jo.Add("nickname", model.NickName);
                    jo.Add("usertype", model.UserType); //(int)UserTypeEnum.Seller
                    jo.Add("token", Token);
                    obj.info = jo;
                }
                else
                {
                    obj.status = false;
                    obj.message = "用户登录失败";
                }
                var resultObj = JsonConvert.SerializeObject(obj, Formatting.Indented);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            #region 用户退出登录,清空Token
            /// <summary>
            /// 用户退出登录,清空Token
            /// </summary>
            /// <param name="userId">用户ID</param>
            /// <returns></returns>
            [Route("api/account/loginout")]
            [HttpGet]
            public HttpResponseMessage LoginOut(int userId)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                try
                {
                    //清空数据库该用户票据数据
                    Dec.BLL.TicketAuth.DeleteByUserId(userId);
                }
                catch (Exception ex) { }
                //返回信息            
                obj.status = true;
                obj.message = "成功退出";
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            #region 查询Token是否有效
            /// <summary>
            /// 查询Token是否有效
            /// </summary>
            /// <param name="token">token</param>
            /// <returns></returns>
            [Route("api/account/validatetoken")]
            [HttpGet]
            public HttpResponseMessage ValidateToken(string token)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                bool flag = ValidateTicket(token);
                if (flag)
                {
                    //返回信息            
                    obj.status = true;
                    obj.message = "token有效";
                }
                else
                {
                    obj.status = false;
                    obj.message = "token无效";
                }
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            #region 获取用户账户余额
            /// <summary>
            /// 获取用户账户余额
            /// </summary>
            /// <param name="userId">用户ID</param>
            /// <returns></returns>
            [Route("api/account/amount")]
            [HttpGet]
            [AuthFilterOutside] //添加验证
            public HttpResponseMessage GetAmount(int userId)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                //获取数据库数据
                Dec.Models.UserInfo model = Dec.BLL.UserInfo.GetUserInfoByUserId(userId);
                if (model != null)
                {
                    //返回信息            
                    obj.status = true;
                    obj.message = "获取用户账户余额成功";
                    JObject jo = new JObject();
                    jo.Add("userid", model.UserId);
                    jo.Add("amount", model.Amount);
                    obj.info = jo;
                }
                else
                {
                    obj.status = false;
                    obj.message = "获取用户账户余额失败";
                }
    
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
            #endregion
    
            /// <summary>
            /// 用户充值接口
            /// </summary>
            /// <param name="userid">用户ID</param>
            /// <param name="amount">充值金额</param>
            /// <returns></returns>
            [Route("api/account/recharge")]
            [HttpGet]
            [AuthFilterInside]
            public HttpResponseMessage Recharge(string userid, double amount)
            {
                //定义
                ResponseResult obj = new ResponseResult();
                //获取数据库数据
    
                //返回信息            
                obj.status = true;
                obj.message = "操作成功,请等待第三方支付平台返回通知核实是否到账";
                JObject jo = new JObject();
                jo.Add("userid", "123456789");
                jo.Add("amount", 125.80);
                obj.info = jo;
    
                var resultObj = JsonConvert.SerializeObject(obj);
                HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json") };
                return result;
            }
    
             #region 验证票据是否有效
            /// <summary>
            /// 验证票据是否有效
            /// </summary>
            /// <param name="encryptToken">token</param>
            /// <returns></returns>
            private bool ValidateTicket(string encryptToken)
            {
                bool flag = false;
                try
                {
                    //获取数据库Token
                    Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);
                    if (model.Token == encryptToken) //存在
                    {
                        //未超时
                        flag = (DateTime.Now <= model.ExpireDate) ? true : false;
                    }
                }
                catch (Exception ex) { }
                return flag;
            }
            #endregion
    
            #region 用户登录
            /// <summary>
            /// 用户登录
            /// </summary>
            /// <param name="userName">用户名</param>
            /// <param name="userPwd">密码</param>
            /// <returns></returns>
            private Dec.Models.UserInfo GetLoginModel(string userName, string userPwd)
            {
                Dec.Models.UserInfo model = new Dec.Models.UserInfo();
                try
                {
                    if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(userPwd))
                    {
                        //数据库比对
                        model = Dec.BLL.UserInfo.GetUserInfoByUserNamePwd(userName, UntilHelper.Md5Encode(userPwd, 32));
                    }
                }
                catch (Exception ex) { }
                return model;
            }
            #endregion
        }
    }
    
    //
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace SpiderApi
    {
        public class WebApiApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                //WebApi文档
                AreaRegistration.RegisterAllAreas();
                GlobalConfiguration.Configure(WebApiConfig.Register);
            }
    
            protected void Application_PostAuthorizeRequest()
            {
                //Enable Session
                HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
            }
        }
    }
    
    // Uncomment the following to provide samples for PageResult<T>. Must also add the Microsoft.AspNet.WebApi.OData
    // package to your project. 先安装Help Page包  HelpPage=>App_start=>HelpPageConfig.cs
    #define Handle_PageResultOfT
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Net.Http.Headers;
    using System.Reflection;
    using System.Web;
    using System.Web.Http;
    using SpiderApi.Models;
    #if Handle_PageResultOfT
    using System.Web.Http.OData;
    #endif
    
    namespace SpiderApi.Areas.HelpPage
    {
        /// <summary>
        /// Use this class to customize the Help Page.
        /// For example you can set a custom <see cref="System.Web.Http.Description.IDocumentationProvider"/> to supply the documentation
        /// or you can provide the samples for the requests/responses.
        /// </summary>
        public static class HelpPageConfig
        {
            [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
                MessageId = "SpiderApi.Areas.HelpPage.TextSample.#ctor(System.String)",
                Justification = "End users may choose to merge this string with existing localized resources.")]
            [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly",
                MessageId = "bsonspec",
                Justification = "Part of a URI.")]
            public static void Register(HttpConfiguration config)
            {
                 Uncomment the following to use the documentation from XML documentation file.
                //开启解析
                config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/Bin/SpiderApi.XML")));
    
                 Uncomment the following to use "sample string" as the sample for all actions that have string as the body parameter or return type.
                 Also, the string arrays will be used for IEnumerable<string>. The sample objects will be serialized into different media type 
                 formats by the available formatters.
                //config.SetSampleObjects(new Dictionary<Type, object>
                //{
                //    {typeof(string), "sample string"},
                //    {typeof(IEnumerable<string>), new string[]{"sample 1", "sample 2"}}
                //});
                //添加映射
                config.SetSampleResponse(Sample.BatchSendMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchSendMessage");
                config.SetSampleResponse(Sample.BatchReceiveMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchReceiveMessage");
                config.SetSampleResponse(Sample.DeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "DeleteMessage");
                config.SetSampleResponse(Sample.BatchDeleteMessageResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "BatchDeleteMessage");
                config.SetSampleResponse(Sample.ChangeMessageVisibilityResponse(), new MediaTypeHeaderValue("text/json"), "MessageQueue", "ChangeMessageVisibility");
    
                // Extend the following to provide factories for types not handled automatically (those lacking parameterless
                // constructors) or for which you prefer to use non-default property values. Line below provides a fallback
                // since automatic handling will fail and GeneratePageResult handles only a single type.
    #if Handle_PageResultOfT
                config.GetHelpPageSampleGenerator().SampleObjectFactories.Add(GeneratePageResult);
    #endif
    
                // Extend the following to use a preset object directly as the sample for all actions that support a media
                // type, regardless of the body parameter or return type. The lines below avoid display of binary content.
                // The BsonMediaTypeFormatter (if available) is not used to serialize the TextSample object.
                config.SetSampleForMediaType(
                    new TextSample("Binary JSON content. See http://bsonspec.org for details."),
                    new MediaTypeHeaderValue("application/bson"));
    
                 Uncomment the following to use "[0]=foo&[1]=bar" directly as the sample for all actions that support form URL encoded format
                 and have IEnumerable<string> as the body parameter or return type.
                //config.SetSampleForType("[0]=foo&[1]=bar", new MediaTypeHeaderValue("application/x-www-form-urlencoded"), typeof(IEnumerable<string>));
    
                 Uncomment the following to use "1234" directly as the request sample for media type "text/plain" on the controller named "Values"
                 and action named "Put".
                //config.SetSampleRequest("1234", new MediaTypeHeaderValue("text/plain"), "Values", "Put");
    
                 Uncomment the following to use the image on "../images/aspNetHome.png" directly as the response sample for media type "image/png"
                 on the controller named "Values" and action named "Get" with parameter "id".
                //config.SetSampleResponse(new ImageSample("../images/aspNetHome.png"), new MediaTypeHeaderValue("image/png"), "Values", "Get", "id");
    
                 Uncomment the following to correct the sample request when the action expects an HttpRequestMessage with ObjectContent<string>.
                 The sample will be generated as if the controller named "Values" and action named "Get" were having string as the body parameter.
                //config.SetActualRequestType(typeof(string), "Values", "Get");
    
                 Uncomment the following to correct the sample response when the action returns an HttpResponseMessage with ObjectContent<string>.
                 The sample will be generated as if the controller named "Values" and action named "Post" were returning a string.
                //config.SetActualResponseType(typeof(string), "Values", "Post");
            }
    
    #if Handle_PageResultOfT
            private static object GeneratePageResult(HelpPageSampleGenerator sampleGenerator, Type type)
            {
                if (type.IsGenericType)
                {
                    Type openGenericType = type.GetGenericTypeDefinition();
                    if (openGenericType == typeof(PageResult<>))
                    {
                        // Get the T in PageResult<T>
                        Type[] typeParameters = type.GetGenericArguments();
                        Debug.Assert(typeParameters.Length == 1);
    
                        // Create an enumeration to pass as the first parameter to the PageResult<T> constuctor
                        Type itemsType = typeof(List<>).MakeGenericType(typeParameters);
                        object items = sampleGenerator.GetSampleObject(itemsType);
    
                        // Fill in the other information needed to invoke the PageResult<T> constuctor
                        Type[] parameterTypes = new Type[] { itemsType, typeof(Uri), typeof(long?), };
                        object[] parameters = new object[] { items, null, (long)ObjectGenerator.DefaultCollectionSize, };
    
                        // Call PageResult(IEnumerable<T> items, Uri nextPageLink, long? count) constructor
                        ConstructorInfo constructor = type.GetConstructor(parameterTypes);
                        return constructor.Invoke(parameters);
                    }
                }
    
                return null;
            }
    #endif
        }
    }
    /*
    API接口测试工具 - WebApiTestClient使用--Nuget引入组件 
    --A Simple Test Client for ASP.NET Web API
    */
    /*
    1、修改Api.cshtml文件
    通过上述步骤,就能将组件WebAPITestClient引入进来。下面我们只需要做一件事:打开文件 (根据 Areas\HelpPage\Views\Help) Api.cshtml 并添加以下内容:
    
    @Html.DisplayForModel("TestClientDialogs")
    @Html.DisplayForModel("TestClientReferences")
    添加后Api.cshtml文件的代码如下
    */
    
    
    @using System.Web.Http
    @using WebApiTestClient.Areas.HelpPage.Models
    @model HelpPageApiModel
    
    @{
        var description = Model.ApiDescription;
        ViewBag.Title = description.HttpMethod.Method + " " + description.RelativePath;
    }
    
    <link type="text/css" href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
    <div id="body" class="help-page">
        <section class="featured">
            <div class="content-wrapper">
                <p>
                    @Html.ActionLink("Help Page Home", "Index")
                </p>
            </div>
        </section>
        <section class="content-wrapper main-content clear-fix">
            @Html.DisplayForModel()
        </section>
    </div>
    
    @Html.DisplayForModel("TestClientDialogs")
    @section Scripts{
        <link href="~/Areas/HelpPage/HelpPage.css" rel="stylesheet" />
        @Html.DisplayForModel("TestClientReferences")
    }


    转载于:https://www.cnblogs.com/smartsmile/p/6234054.html

    展开全文
  • WebApi_Token

    2018-08-06 16:40:38
    WEBAPI+TOKEN验证 token+签名认证的主要原理是:1.做一个认证服务,提供一个认证的webapi,用户先访问它获取对应的token 2.用户拿着相应的token以及请求的参数和服务器端提供的签名算法计算出签名后再去访问指定的...
  • web api JWT token认证

    2020-04-24 11:20:26
    web api JWT token认证 Demo 代码,包含跨域访问 api设置。
  • webAPI Token

    2019-03-18 11:13:33
    Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.2.7 Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0 Install-Package Microsoft.AspNet.Identity.Owin -Version 2.2.2 Install-...

    1. 引用包:

    Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.2.7
    Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0
    Install-Package Microsoft.AspNet.Identity.Owin -Version 2.2.2
    Install-Package Microsoft.Owin.Cors -Version 4.0.1 
    Install-Package EntityFramework -Version 6.2.0

     

    2. 添加Startup类

        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                HttpConfiguration config = new HttpConfiguration();
                ConfigureOAuth(app);

                WebApiConfig.Register(config);
                app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
                app.UseWebApi(config);
            }
            public void ConfigureOAuth(IAppBuilder app)
            {
                OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
                {
                    AllowInsecureHttp = true,
                    //AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
                    TokenEndpointPath = new PathString("/token"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),
                    Provider = new SimpleAuthorizationServerProvider(),
                    RefreshTokenProvider = new OpenRefreshTokenProvider()
                };
                app.UseOAuthAuthorizationServer(OAuthServerOptions);
                app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
            }
        }

     

    3. 添加SimpleAuthorizationServerProvider类

     

     

    4. 添加OpenRefreshTokenProvider类

     

     

     

     

     

     

     

     

     

     

     

     

    参考:

    https://www.cnblogs.com/Irving/p/4810131.html
    https://blog.csdn.net/li_mancheng/article/details/71515717
    https://www.cnblogs.com/dudu/p/4679592.html
    https://www.cnblogs.com/Irving/p/4607104.html
    https://www.cnblogs.com/dudu/p/oauth-refresh-token.html
    https://blog.csdn.net/kebi007/article/details/72861532
    https://blog.csdn.net/syrs1987/article/details/82990100
    https://blog.csdn.net/qq285679784/article/details/80203232
    https://blog.csdn.net/u010265681/article/details/76651766/
    https://www.cnblogs.com/lnice/p/6857203.html
    https://www.cnblogs.com/huangziqing/p/7710315.html
    https://cloud.tencent.com/developer/ask/121293
    https://www.cnblogs.com/zxh1919/p/7764219.html
    https://www.cnblogs.com/zxh1919/p/7670118.html
    https://www.cnblogs.com/richieyang/p/4918819.html
    http://www.cnblogs.com/richieyang/p/4918819.html
    https://www.cnblogs.com/sword-successful/p/5701610.html
    https://www.cnblogs.com/dukang1991/p/5627584.html
    https://www.cnblogs.com/zxh1919/p/7764219.html
    https://www.cnblogs.com/wuhuacong/p/4620300.html

    展开全文
  • using System; using System.Linq; using System.Web; ...using System.Web.Http;...using System.Web.Security;...namespace OtherApi.Auth { public class AuthFilterOutside : AuthorizeAttribute ...
  • webapi token

    2018-10-09 22:33:00
    /// Token实体 /// &lt;/summary&gt; public class TokenEntity { /// &lt;summary&gt; /// token字符串 /// &lt;/summary&gt; public string access_token { get; set; } /// ...
  • Web Api Token验证

    千次阅读 2018-10-04 20:27:29
    我最近刚学习web api,所以写的一token认证比较简单 1、新建一个web api的项目 2、打开Provides中的这个类 3、在这个类的GrantResourceOwnerCredentials方法中进行认证修改 4、注释掉这个方法中的东西,自己...
  • Is is possible to attach Refresh Token to the api response? I would not use Implicit Fow in the js app. Thanks </p><p>该提问来源于开源项目:IdentityServer/IdentityServer3</p></div>
  • webAPI token验证

    2019-10-07 01:23:31
    ASP.NET WebApi 实现Token验证 https://www.cnblogs.com/dukang1991/p/5627584.html 转载于:https://www.cnblogs.com/KQNLL/p/9757025.html
  • WebAPI Token 验证

    2018-05-11 17:03:00
    WebAPI Token 验证 登录端 //HttpContext.Current.Session.Timeout = 10; ////生成Ticket //FormsAuthenticationTicket token = new FormsAuthenticationTicket(0,req.LUsername,DateTime.Now,...
  • 那如何解决呢,这里介绍一种使用JWT 产生Token,为每个方法加一个Token的身份验证,这样,用户在正常登录后,获取到系统为该用户产生的Token,以后,每次调用服务端的WebApi方法时,都需要把这个Token送到服务端做...
  • java http请求token验证调用.net webapi接口public void test191120() {String url ="http://xxx/api/Test1";try {URL uRl = new URL(url);HttpURLConnection httpConnection =(HttpURLConnection) uRl.open...
  • WebApi安全性 使用TOKEN+签名验证
  • C# webapi编写Token+数字签名前后台代码。主要用于自我学习记录。所以根据网上查找和自己需求就自己写了一份Token+数字签名的WebAPI程序
  • Asp.Net MVC webAPI Token based authentication

    千次阅读 2017-07-28 00:06:04
    Asp.Net MVC webAPI Token based authentication
  • 令牌概述(Token) 在以用户账号体系作为安全认证的信息系统中,对用户身份的鉴定是非常重要的事情。 令牌机制是软件系统安全体系中非常重要的部分,在计算机身份认证中是令牌的意思,一般作为邀请、登录...
  • web api token验证理解

    2019-09-23 07:31:33
    最近一直在学习web api authentication,以Jwt为例,可以这样理解,token是身份证,用户名和密码是户口本,身份证是有有效期的(jwt 有过期时间),且携带方便(自己带有所有信息self contained),户口本不会过期...
  • ABP从入门到精通(4) 使用基于JWT标准的Token访问WebApi

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,736
精华内容 2,294
关键字:

tokenwebapi