在IIS上托管的ASP.NET Web API中实现JWT Bearer令牌身份验证
在IIS上托管的ASP.NET Web API中实现JWT bearer令牌身份验证,与.NET Core或OWIN应用程序相比,需要采用不同的方法。本文提供了一个全面的指南,介绍如何实现这种身份验证机制,并解答关键问题:
如何生成JWT令牌?
要生成JWT令牌,可以使用System.IdentityModel.Tokens.Jwt NuGet包。以下是用HMACSHA256和对称密钥的示例:
<code class="language-csharp">const string Secret = "db3OIsj+BXE9NZDy0t8W3TcNekrF+2d/1sFnWG4HnV8TZY30iTOdtVWJG8abWvB1GlOgJuQZdcF2Luqm/hccMw=="; public static string GenerateToken(string username, int expireMinutes = 20) { var symmetricKey = Convert.FromBase64String(Secret); var tokenHandler = new JwtSecurityTokenHandler(); var now = DateTime.UtcNow; var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, username) }), Expires = now.AddMinutes(Convert.ToInt32(expireMinutes)), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature) }; var stoken = tokenHandler.CreateToken(tokenDescriptor); var token = tokenHandler.WriteToken(stoken); return token; }</code>
如何提供JWT令牌?
一种简单的方法是在控制器操作中创建一个令牌端点:
<code class="language-csharp">public class TokenController : ApiController { [AllowAnonymous] public string Get(string username, string password) { if (CheckUser(username, password)) { return JwtManager.GenerateToken(username); } throw new HttpResponseException(HttpStatusCode.Unauthorized); } public bool CheckUser(string username, string password) { // 应该在数据库中检查 return true; } }</code>
如何验证JWT令牌?
另一种方法是创建一个从IAuthenticationFilter继承的JWTAuthenticationAttribute:
<code class="language-csharp">private static bool ValidateToken(string token, out string username) { username = null; var simplePrinciple = JwtManager.GetPrincipal(token); var identity = simplePrinciple.Identity as ClaimsIdentity; if (identity == null || !identity.IsAuthenticated) return false; var usernameClaim = identity.FindFirst(ClaimTypes.Name); username = usernameClaim?.Value; if (string.IsNullOrEmpty(username)) return false; // 更多验证以检查系统中用户名是否存在 return true; } protected Task<IPrincipal> AuthenticateJwtToken(string token) { string username; if (ValidateToken(token, out username)) { // 从数据库中的用户名获取更多信息 var claims = new List<Claim> { new Claim(ClaimTypes.Name, username) }; var identity = new ClaimsIdentity(claims, "Jwt"); IPrincipal user = new ClaimsPrincipal(identity); return Task.FromResult(user); } return Task.FromResult<IPrincipal>(null); }</code>
此属性可以应用于特定操作:
<code class="language-csharp">public class ValueController : ApiController { [JwtAuthentication] public string Get() { return "value"; } }</code>
通过中间件或DelegateHandler验证JWT令牌?
OWIN中间件或DelegateHandler也可以用于验证Web API的所有传入请求。
验证JWT令牌
以下代码验证JWT令牌并返回主体:
<code class="language-csharp">public static ClaimsPrincipal GetPrincipal(string token) { try { var tokenHandler = new JwtSecurityTokenHandler(); var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken; if (jwtToken == null) return null; var symmetricKey = Convert.FromBase64String(Secret); var validationParameters = new TokenValidationParameters() { RequireExpirationTime = true, ValidateIssuer = false, ValidateAudience = false, IssuerSigningKey = new SymmetricSecurityKey(symmetricKey) }; SecurityToken securityToken; var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken); return principal; } catch (Exception) { // 记录异常 return null; } }</code>
授权
请记住全局添加config.Filters.Add(new AuthorizeAttribute());
以防止匿名请求。
以上是如何在 IIS 上托管的 ASP.NET Web API 中实现 JWT 不记名令牌身份验证?的详细内容。更多信息请关注PHP中文网其他相关文章!