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一下,防篡改),这样就和微信那套机制就差不多了! 嘻嘻!

规则我们自己来定,欢迎大家提出有建议性的回复,谢谢

 

 

 

 

 

posted @   天天向上518  阅读(1130)  评论(0编辑  收藏  举报
编辑推荐:
· 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工具
点击右上角即可分享
微信分享提示