JWT验证集成

API数据交互过程中往往需要安全验证,但组件并不直接提供这方向面的支持;由于组件是基于标准HTTP协议的实现,所有基于这协议的验证规则都可以根据实际情况来扩展。以下是针对JWT验证的一个扩展,并添加的服务应用中。为了实现这一验证功能需要添加一个相关组件System.IdentityModel.Tokens.Jwt

实现JWT Helper

复制代码
 public class JWTHelper
    {
        private string mIssuer = null;

        private string mAudience = null;

        private SecurityKey mSecurityKey;

        private SigningCredentials mSigningCredentials;

        private TokenValidationParameters mTokenValidation = new TokenValidationParameters();

        private JwtSecurityTokenHandler mJwtSecurityTokenHandler = new JwtSecurityTokenHandler();

        public JWTHelper() : this(null, null)
        {

        }

        public JWTHelper(string issuer, string audience, string key = "2qyg4coej88uqrono0xdmx4y0il5dn5y7b72tlb3imba677ht1p1xlfcnh36mk5u3xzjktfara29axvzk85apfplun7oslbe1m20c148p5d519kja5wvg7lmn5v4a5ou")
        {
            mIssuer = issuer;
            mAudience = audience;
            mSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
            if (string.IsNullOrEmpty(mIssuer))
            {
                mTokenValidation.ValidateIssuer = false;
            }
            else
            {
                mTokenValidation.ValidIssuer = mIssuer;
            }
            if (string.IsNullOrEmpty(mAudience))
            {
                mTokenValidation.ValidateAudience = false;
            }
            else
            {
                mTokenValidation.ValidAudience = mAudience;
            }
            mTokenValidation.IssuerSigningKey = mSecurityKey;
            mSigningCredentials = new SigningCredentials(mSecurityKey, SecurityAlgorithms.HmacSha256);
            Expires = 60 * 24;
        }

        public int Expires { get; set; }

        public string CreateToken(string name, string role)
        {
            ClaimsIdentity claimsIdentity = new ClaimsIdentity();
            claimsIdentity.AddClaim(new Claim("Name", name));
            claimsIdentity.AddClaim(new Claim("Role", role));
            var item = mJwtSecurityTokenHandler.CreateEncodedJwt(mIssuer, mAudience, claimsIdentity, DateTime.Now.AddMinutes(-5),
                DateTime.Now.AddMinutes(100), DateTime.Now,
               mSigningCredentials);
            return item;
        }

        public ClaimsPrincipal ValidateToken(string token)
        {
            return mJwtSecurityTokenHandler.ValidateToken(token, mTokenValidation, out var securityToken);
        }

        public UserInfo GetUserInfo(string token)
        {
            UserInfo userInfo = new UserInfo();
            if (!string.IsNullOrEmpty(token))
            {
                var info = ValidateToken(token);
                ClaimsIdentity identity = info?.Identity as ClaimsIdentity;
                userInfo.Name = identity?.Claims?.FirstOrDefault(c => c.Type == "Name")?.Value;
                userInfo.Role = identity?.Claims?.FirstOrDefault(c => c.Type == "Role")?.Value;
            }
            return userInfo;
        }

        public struct UserInfo
        {
            public string Name;

            public string Role;
        }
    }
复制代码

以上封装只是简单地提供了用户名称和角色两项信息,不过一般情况这两信息可以满足普通验证的需要;如果有更多的信息需求可以根据实际情况添加,不过信息越多那对应的Token内容就越大。

创建Token

var token=JWTHelper.CreateToken(name, role);

通过以上代码创建一个JWTToken

定义组件验证过虑器

可以通过虑器的方式引入到组件中,这样就可以在不修改控制器逻辑的情况进行安全验证。过虑器实现如下:

复制代码
    public class JWTFilter : FilterAttribute
    {
        public override bool Executing(ActionContext context)
        {
            string token = context.HttpContext.Request.Header[HeaderTypeFactory.AUTHORIZATION];
            var user = Program.JWTHelper.GetUserInfo(token);
            if (!string.IsNullOrEmpty(user.Name))
            {
                return true;
            }
            else
            {
                context.Result = new TextResult("token not found");
                return false;
            }
        }
    }
复制代码

重写Executing方法,获取请求头相关Token信息并获取相关用户信息,当获取的用户名是正确的情况则返回true继续执行,否则返回一个相关的错误信息。

使用

复制代码
        public object GetToken(string name, string role)
        {
            return new TextResult(JWTHelper.CreateToken(name, role));
        }
        [JWTFilter]
        public object GetTime()
        {
            return DateTime.Now;
        }
复制代码

以上有两个方法,一个是不需要验证创建并返回一个Token,而另一个获取时间的方法则需要验证通过后才能获取。

posted @   beetlex  阅读(550)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2018-09-17 dotnet core高吞吐Http api服务组件FastHttpApi
2014-09-17 azure存储压测的问题(农码主观意识太强被坑了)
点击右上角即可分享
微信分享提示