引言
在现代Web应用中,安全地验证用户身份是至关重要的。JSON Web Tokens(JWT)作为一种流行的无状态身份验证机制,提供了一种安全、高效的方式来处理分布式系统中的用户认证问题。本文将详细探讨如何在.NET Core应用程序中配置和使用JWT进行身份验证。
理解JWT
JWT是一种紧凑且自包含的方式,用于在各方之间以JSON对象的形式安全地传输信息。它可用于身份验证和信息交换,具有以下特点:
- 无状态和可扩展性:JWT 不依赖于服务器存储会话信息,易于在分布式系统中扩展。
- 跨域认证:JWT 可以轻松地在不同域之间传递,适用于单点登录(SSO)场景。
- 安全性:使用强加密算法确保令牌的安全性。
- 自包含:令牌内包含所有用户状态信息,无需查询数据库。
前提条件
在开始之前,请确保环境中已安装了以下工具和库:
- .NET Core SDK
- Visual Studio Code或Visual Studio
- NuGet包管理器
- JWT相关库,如
System.IdentityModel.Tokens.Jwt
和Microsoft.IdentityModel.Tokens
步骤1:配置JWT认证服务
首先找到项目中的Startup.cs 进行配置JWT认证服务
services.AddSwaggerGen(c =>
{
//向 API 文档中的响应(Response)中添加自定义的响应头(Response Headers)
c.OperationFilter<AddResponseHeadersFilter>();
//向 API 文档中的每个 API 操作的摘要(Summary)中添加授权信息(Authorization)
c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
//向 API 文档中的每个 API 操作添加安全要求(Security Requirements)
c.OperationFilter<SecurityRequirementsOperationFilter>("Bearer");//安全定 义名
//添加安全定义
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Description = "直接在下框中输入Bearer {token}(注意两者之间是一个空格)",
Name = "Authorization",
BearerFormat = "JWT",
Scheme = "Bearer"
});
//添加安全要求
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference=new OpenApiReference
{
Type=ReferenceType.SecurityScheme,
Id="Bearer"
},
/*Scheme="Bearer",
BearerFormat = "JWT",
Name = "Authorization",
In = ParameterLocation.Header,
Type=SecuritySchemeType.ApiKey,*/
},
new string[] {}
}
});
});
#region JWT
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("JwtAuthorize:Secret")?.Value ?? "")),//"SDMC-CJAS1-SAD-DFSFA-SADHJVF"
ValidateIssuer = true,
ValidIssuer = Configuration.GetSection("JwtAuthorize:Issuer")?.Value ?? "",
ValidateAudience = true,
ValidAudience = Configuration.GetSection("JwtAuthorize:Audience")?.Value ?? "",
ValidateLifetime = true,
ClockSkew = TimeSpan.FromDays(1)//令牌失效时间
};
});
#endregion
步骤2:配置JWT认证服务
找到Configure添加鉴权
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthentication();//添加鉴权
app.UseAuthorization();
}
步骤3:创建身份验证控制器
创建一个控制器来处理登录并发放JWT(这里只做简易测试 后续根据自己业务存储一些用户基本信息):
[Authorize]
[ApiController]
[Route("api/[Controller]/[action]")]
public class SupplierController : BaseController
{
//这里生成了Token
[AllowAnonymous] //跳过授权验证
[HttpPost]
public async Task<string> GetTokenTest()
{
//登录成功
var claims = new Claim[]
{
/*new Claim(ClaimTypes.Name,writer.WriteName),
new Claim("ID",writer.ID.ToString()),
new Claim("UserName",writer.WriteLoginName),*/
};
//issuer代表颁发Token的Web应用程序,audience是Token的受理者
var token = new JwtSecurityToken(
issuer: _configuration.GetSection("JwtAuthorize:Issuer")?.Value ?? "",
audience: _configuration.GetSection("JwtAuthorize:Audience")?.Value ?? "",
claims: claims,
notBefore: DateTime.Now,
expires: DateTime.Now.AddDays(1),//token有效时间
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.GetSection("JwtAuthorize:Secret")?.Value ?? "")), SecurityAlgorithms.HmacSha256)
);
var jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
return jwtToken;
}
}
生成了Token后再增加一个接口用于测试授权
//[AllowAnonymous] 没有这个的话就需要进行授权验证通过后才可调用到接口
[HttpPost]
public async Task<string> getTk(int id)
{
return "";
}
运行项目后调用该接口后得到的结果如下:
401错误场景
1. 用户未登录,代码报401,应该回到登录页
2. 登录用户的token过期
步骤4:测试JWT鉴权
由此可见,这个就需要用户登录后的Token信息 或者Token过期了 那么就没有权限访问了。
所以在这之前需要模拟登录操作得到Token返回给前端进行存储
调用GetTokenTest方法获取Token
得到Token后就需要在需要访问调用的接口下增加Authorization,下面使用PostMan测试工具再次测试getTK这个接口方法看能否成功调用
结论
通过上述步骤,成功在.NET Core应用程序中配置了JWT鉴权。JWT提供了一种灵活、安全的方式来处理身份验证和授权,适用于需要高扩展性和安全性的Web应用。