.NET Framework 中对webapi进行jwt验证

最近在项目中对webapi进行了jwt验证,做一个记录

  1. 有关于jwt生成和验证token的操作全部记录在jwthelper.cs文件中:
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/// <summary>
/// 授权JWT类
/// </summary>
public class JwtHelper
{
    public readonly string SecretKey = System.Configuration.ConfigurationManager.AppSettings["SecretKey"];
    public readonly string AppId = System.Configuration.ConfigurationManager.AppSettings["AppId"];
    public readonly string AppKey = System.Configuration.ConfigurationManager.AppSettings["AppKey"];
    /// <summary>
    /// 创建Token 这里面可以保存自己想要的信息
    /// </summary>
    /// <param name="user_id"></param>
    /// <param name="mobile"></param>
    /// <returns></returns>
    public string CreateToken(string user_id)
    {
        // 1. 定义需要使用到的Claims
        var claims = new Claim[]
        {
            new Claim("user_id", user_id),           
            /* 可以保存自己想要信息,传参进来即可          
            new Claim("limit", "limit"),           
            */
        };
 
        // 2. 从 appsettings.json 中读取SecretKey
        var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));
 
        // 3. 选择加密算法
        var algorithm = SecurityAlgorithms.HmacSha256;
 
        // 4. 生成Credentials
        var signingCredentials = new SigningCredentials(secretKey, algorithm);
 
        // 5. 根据以上,生成token
        var jwtSecurityToken = new JwtSecurityToken(
           issuer: AppId,    //Issuer
           audience: AppKey,  //Audience
           claims: claims,                          //Claims,
           notBefore: DateTime.Now,                    //notBefore
           expires: DateTime.Now.AddHours(1),     //expires
           signingCredentials: signingCredentials               //Credentials
        );
 
        // 6. 将token变为string
        var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
 
        return token;
    }
 
    /// <summary>
    /// 根据token反向解析
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    public string GetInfoFromToken(string token = null)
    {
        if (token is null || token == "")
            return null;
 
        string tokenStr = token.Replace("Bearer ", "");
 
        var handler = new JwtSecurityTokenHandler();
        // string tokenStr = token;
        var payload = handler.ReadJwtToken(tokenStr).Payload;
 
        var claims = payload.Claims;
 
        var userid = claims.First(claim => claim.Type == "user_id")?.Value;
        return userid;
    }
 
    /// <summary>
    /// 从Token中获取用户身份
    /// </summary>
    /// <param name="token"></param>
    /// <param name="securityKey">securityKey明文,Java加密使用的是Base64</param>
    /// <returns></returns>
    public ClaimsPrincipal GetPrincipal(string token)
    {
        try
        {
            string securityKey = SecretKey;
            token = token.Replace("Bearer ", "");
            var handler = new JwtSecurityTokenHandler();
            TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
            {
                ValidateAudience = false,
                ValidateIssuer = false,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey)),
                ValidateLifetime = false
            };
            return handler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
        }
        catch (Exception ex)
        {
 
            return null;
        }
    }
 
    /// <summary>
    /// 校验Token
    /// </summary>
    /// <param name="token">token</param>
    /// <returns></returns>
    public bool CheckToken(string token)
    {
        var principal = GetPrincipal(token);
        if (principal is null)
        {
            return false;
        }
        return true;
    }

  2. 控制器中添加获取token的方法

复制代码
        /// <summary>
        /// 获取Token
        /// </summary>
        /// <returns></returns>
        [System.Web.Http.HttpGet]
        public async Task<string> GetToken(string userid)
        {
            //参数验证等等....
            if (string.IsNullOrEmpty(userid))
            {
                return await Task.FromResult("参数异常!");
            }
            //这里可以连接数据库做账号密码验证
            //这里可以做Redis缓存验证等等
            //这里获取Token
            var token = await Task.Run(() => { return _jwt.CreateToken(userid); });
            return token;
        }
复制代码

根据该访问获取到token

 

 

 

 

2. 自定义SaveImgAttribute,继承ActionFilterAttribute过滤器并重写OnActionExecuting()方法

复制代码
 public class SaveImgAttribute : ActionFilterAttribute
    {

        public readonly string SecretKey = System.Configuration.ConfigurationManager.AppSettings["SecretKey"];
        public readonly string AppId = System.Configuration.ConfigurationManager.AppSettings["AppId"];
        public readonly string AppKey = System.Configuration.ConfigurationManager.AppSettings["AppKey"];

        // 调用方法前
        public override void OnActionExecuting(ActionExecutingContext actionContext)
        {
            Jwt.JwtHelper _jwt = new Jwt.JwtHelper();
            var token = "";
            if (actionContext.HttpContext.Request.Headers.AllKeys.Contains("Authorization"))
            {
                int index = actionContext.HttpContext.Request.Headers.AllKeys.Select((a, i) => i).Where(i => actionContext.HttpContext.Request.Headers.AllKeys[i] == "Authorization").FirstOrDefault();
                token = actionContext.HttpContext.Request.Headers[index];
            }
            if (token == null || token == "")
            {
                var Auth = new
                {
                    Status = 401,
                    Message = "身份验证失败"
                };
                actionContext.Result = new ContentResult
                {
                    ContentType = "application/json",
                    Content = JsonConvert.SerializeObject(Auth)
                };
                return;
            }
            bool isOK = _jwt.CheckToken(token);
            if (!isOK)
            {
                var Auth = new
                {
                    Status = 401,
                    Message = "身份验证失败"
                };
                actionContext.Result = new ContentResult
                {
                    ContentType = "application/json",
                    Content = JsonConvert.SerializeObject(Auth)
                }; return;

            }
            var userid = _jwt.GetInfoFromToken(token);
             
            base.OnActionExecuting(actionContext);
        }


    }
复制代码

 3. 在控制器方法上加上[SaveImg]特性即可,每次调用对应方法的时候都会在SaveImgAttribute中进行 token验证

        [SaveImg]
        [System.Web.Http.HttpPost]
        public async Task<JsonResult> SaveFileToOSS([FromBody] RequestBody request)
        {.....}

将GetToken()获取到的token添加到http请求头中(key:Authorization)(value:Bearer+空格+token)再进行对应方法的请求

 

posted @   没有童话的鱼  阅读(265)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示