雖然這裡已經有很多人寫過ASP.NET Core使用JWT,但我還是想紀錄自己的版本
1.安裝指令dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
2.建立jwtSettings.cs
public class JwtSettings
{
public string Issuer { get; set; } = null!;
public string Audience { get; set; } = null!;
public string Key { get; set; } = null!;
}
"JWT": {
"Key": "YourSecretKeyHere",
"Issuer": "YourIssuer",
"Audience": "YourAudience"
}
var jwtSettings = builder.Configuration.GetSection("JWT").Get<JwtSettings>()
?? throw new InvalidOperationException("JWT settings are missing");
builder.Services.AddSingleton(jwtSettings);
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Key))
};
});
app.UseAuthentication();
app.UseAuthorization();
builder.Services.AddOpenApiDocument(options =>
{
options.PostProcess = document =>
{
document.Info = new NSwag.OpenApiInfo
{
Version = "v1",
Title = "Leni API",
Description = "An ASP.NET Core Web API for article platform"
};
};
options.AddSecurity("JWT", new NSwag.OpenApiSecurityScheme
{
Type = NSwag.OpenApiSecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT",
Name = "Authorization",
In = NSwag.OpenApiSecurityApiKeyLocation.Header,
Description = "Enter your JWT token"
});
options.OperationProcessors.Add(
new NSwag.Generation.Processors.Security.AspNetCoreOperationSecurityScopeProcessor("JWT")
);
});
private string GenerateJwtToken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(_jwtSettings.Key);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Account),
new Claim(ClaimTypes.Name, user.Name??String.Empty),
// 可加入更多自訂 Claims
}),
Expires = DateTime.UtcNow.AddHours(1),
Issuer = _jwtSettings.Issuer,
Audience = _jwtSettings.Audience,
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
// 這裡可以替換簽章演算法
SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
使用Microsoft.AspNetCore.Authorization
在Controller或單一API前加入[Authorize],就會自己驗證囉
使用System.Security.Claims
如果想要從Token解析出Account
可以在API涵式裡呼叫ClaimTypes.NameIdentifier
Configure JWT bearer authentication in ASP.NET Core
使用 dotnet user-jwts 管理開發時期的 JWT Tokens 與 Signing key
小人退散