Implementing JWT Authentication in ASP.NET Web API without OWIN middleware
This article describes how to implement JWT authentication in the old version of ASP.NET Web API without OWIN middleware. The core principle is to issue JWT tokens and validate them when a request is received.
Token generation endpoint
Provides a token endpoint where users can obtain a JWT token, e.g. using a simple implementation of a controller action:
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); } private bool CheckUser(string username, string password) { // 应在数据库中进行检查 return true; // 此处应替换为实际的用户验证逻辑 } }
Use System.IdentityModel.Tokens.Jwt to generate tokens
Generate tokens using System.IdentityModel.Tokens.Jwt NuGet package and HMACSHA256 symmetric key:
/// <summary> /// 使用以下代码生成对称密钥 /// var hmac = new HMACSHA256(); /// var key = Convert.ToBase64String(hmac.Key); /// </summary> private 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(expireMinutes), SigningCredentials = new SigningCredentials( new SymmetricSecurityKey(symmetricKey), SecurityAlgorithms.HmacSha256Signature) }; var stoken = tokenHandler.CreateToken(tokenDescriptor); var token = tokenHandler.WriteToken(stoken); return token; }
Use authentication filter for JWT verification
For JWT validation, create a custom authentication filter inherited from IAuthenticationFilter
:
public class ValueController : ApiController { [JwtAuthentication] // 自定义过滤器属性 public string Get() { return "value"; } }
In the authentication filter, implement the verification logic and return ClaimsPrincipal
:
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); }
JWT verification using JWT library
In order to verify the JWT token and obtain ClaimsPrincipal
, you can use the JWT library:
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; } }
Authorization
To prevent anonymous requests, add the following global configuration:
config.Filters.Add(new AuthorizeAttribute());
Postman Test
Request a token using Postman:
<code>GET http://localhost:{port}/api/token?username=cuong&password=1</code>
Use the obtained JWT token in the header of the authorization request:
<code>GET http://localhost:{port}/api/value Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImN1b25nIiwibmJmIjoxNDc3NTY1MjU4LCJleHAiOjE0Nzc1NjY0NTgsImlhdCI6MTQ3NzU2NTI1OH0.dSwwufd4-gztkLpttZsZ1255oEzpWCJkayR_4yvNL1s</code>
Please note that the CheckUser
methods and error handling parts in the code need to be improved according to actual applications. Secret
Keys should also be stored in a more secure place rather than being hardcoded directly in the code. This is just a simplified example, and more comprehensive security and error handling mechanisms need to be considered in actual applications.
The above is the detailed content of How to Implement JWT Authentication in ASP.NET Web API Without OWIN Middleware?. For more information, please follow other related articles on the PHP Chinese website!