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);
通过以上代码创建一个JWT的Token
定义组件验证过虑器
可以通过虑器的方式引入到组件中,这样就可以在不修改控制器逻辑的情况进行安全验证。过虑器实现如下:
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,而另一个获取时间的方法则需要验证通过后才能获取。
访问Beetlex的Github

浙公网安备 33010602011771号