Asp.net WebApi的授权安全机制 Basic认证
1:Home/index.cshtml下面的Html代码
1 2 3 4 | < div > < input value="1点击先登陆" type="button" id="btnLogin"/>< br /> < input value="2再点击授权后调用接口" type="button" id="btnAuthenrazation" />< br /> </ div > |
2:Home/index 下面的HomeController
[skipLogAttribute] public ActionResult Index() { return View(); }
3: Ajax的模拟代码,先登录,后获取授权,再带上Ticket,后台过滤器校验ok杂可以请求对应的接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <script type= "text/javascript" > $(function () { var ticket = "" ; $( "#btnLogin" ).click(function () { //---登陆的操作 $.ajax({ url: "http://localhost:8899/api/values" , data: { "uid" : "zrf" , "pwd" : "123" }, type: "get" , success: function (res) { if (res.result) { ticket = res.ticket; alert( "授权成功" +res.ticket); } }, dataType: "json" }) }); //----拿到了Ticket(后台过滤器会判断是否有过授权,以及授权ok才可以调用对应的接口) $( "#btnAuthenrazation" ).click(function () { $.ajax({ url: "http://localhost:8899/api/values" , data: { }, type: "get" , beforeSend: function (xhr) { xhr.setRequestHeader( 'Authorization' , 'BasicAuth ' + ticket); //--请求其他的接口都需要带上Ticket的 }, success: function (res) { alert( "ok" ) } }) }); }) //带上Ticket来访问WebApi接口 $( "#btnWithTicket" ).click(function () { $.ajax({ url: "http://localhost:8899/api/values" , data: { "id" :110}, type: "get" , beforeSend: function (xhr) { xhr.setRequestHeader( 'Authorization' , 'BasicAuth ' + ticket); //--请求其他的接口都需要带上Ticket的 }, success: function (res) { if (res.result) { alert( "调用成功" + res.data); } } }) }) |
4: 创建的一个测试的 WebApiController 如ValuesController:ApiController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | namespace WebApplication1.Controllers { using System.Web.Security; using WebApplication1.Filters; public class ValuesController : ApiController { [HttpGet] [skipLog] public dynamic Login( string uid, string pwd) { dynamic result = null ; if ( "zrf" .Equals(uid) && pwd.Equals( "123" )) { FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "account" , DateTime.Now, DateTime.Now.AddSeconds(10), true , $ "uid={uid},pwd={pwd}" ); result = new { result = true , ticket = FormsAuthentication.Encrypt(ticket) }; } else { result = new { result = false , ticket = "" }; } return result; } // GET api/<controller> [skipLogAttribute] public IEnumerable< string > Get() { return new string [] { "value1" , "value2" }; } // GET api/<controller>/5 [CustomerAuthenrazationFilter] public dynamic Get( int id) { return new { result = true , id = id }; } } } |
5:授权过滤器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebApplication1.Filters { using System.Net.Http.Headers; using System.Web.Http.Controllers; using System.Web.Http.Filters; using System.Web.Security; using System.Web.Http; using System.Net; public class CustomerAuthenrazationFilterAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) { skipLogAttribute skiplogin = actionContext.ActionDescriptor.GetCustomAttributes<skipLogAttribute>().FirstOrDefault(); if (skiplogin!= null ) { return ; } AuthenticationHeaderValue headevalue = actionContext.Request.Headers.Authorization; if (headevalue != null ) { string Msg = string .Empty; if (ValidateTicket(headevalue.Parameter, out Msg)) { return ; } else { this .HandlerUnAuthorization(Msg); } } else { this .HandlerUnAuthorization( "请先获取登陆授权的Ticket" ); } } private void HandlerUnAuthorization( string Msg) { throw new Exception(Msg); } private bool ValidateTicket( string parameter, out string Msg) { Msg = string .Empty; if (! string .IsNullOrWhiteSpace(parameter)) { FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(parameter); if (ticket != null ) { if (ticket.Expired) { Msg = "接口时间已经过期,请重新登陆授权!" ; return false ; } if ( string .Equals($ "uid=zrf,pwd=123" , ticket.UserData)) // $"uid={accountID},pwd={pwd}" { Msg = "授权成功!" ; return true ; } else { Msg = "授权失败,请重新登陆授权!" ; return false ; } } } return false ; } } } |
6:自定义的特性,用来跳过权限的验证
1 2 3 4 5 6 7 8 9 10 11 | using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebApplication1.Filters { public class skipLogAttribute:Attribute { } } |
7:在WebApiConfig 文件中来注册一个全局的授权过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | namespace WebApplication1.App_Start { using System.Web.Mvc; public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服务 // Web API 路由 config.MapHttpAttributeRoutes(); config.Filters.Add( new Filters.CustomerAuthenrazationFilterAttribute()); } } } |
8:最后上两张测试的截图:
最后,这个案例只是起到抛砖引玉的作用,大家还可以做得更加的细致及合理
如下:
我们还可以加上随机字符串:A;
时间戳:B(时间精确到秒,方便后续判断,可过期);
唯一的uid C;
pwd D(根据uid来查询数据库并获取到pwd),;
获取自定义的签名Sign:(如:uid+A+B+C+D 这4个值再MD5一下,防篡改),这样就和微信那套机制就差不多了! 嘻嘻!
规则我们自己来定,欢迎大家提出有建议性的回复,谢谢
好了今天就先到这里,下次有时间再更新,如果存在不合理的地方,欢迎大家多多指教留言!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具