前言
.NET6使用JWT(JSON Web Token)进行身份验证和授权
一、权限管理和认证
在.NET 6中,你可以使用ASP.NET Core自带的身份验证和授权中间件来实现接口权限管理和认证
二、使用步骤
1.添加所需的NuGet包
在项目中添加以下NuGet包以支持JWT:
Microsoft.AspNetCore.Authentication.JwtBearer: 提供JWT身份验证支持。
System.IdentityModel.Tokens.Jwt: 提供JWT生成和验证的功能。
配置JWT认证
添加JwtSetting类
public class JwtSettings
{
public string? SecretKey { get; set; }
public string? ExpirationHours { get; set; }
}
自定义User类
public class User
{
public string? UserName { get; set; }
public string? Id { get; set; }
public string? Role { get; set; }
}
在AppSetting文件中添加
"JwtSettings": {
"SecretKey": "YOUR_SECRET_KEY",//key不能太短
"ExpirationHours": 24
}
在Program.cs文件的ConfigureServices方法中配置JWT认证。
#region Jwt配置
//读取配置文件
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
// 配置JWT认证
builder.Services.Configure<JwtSettings>(configuration.GetSection("JwtSettings"));//将Jwt配置注入
var jwtSettings = configuration.GetSection("JwtSettings").Get<JwtSettings>();
var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey??"");
builder.Services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(option=>{
option.RequireHttpsMetadata = false;
option.SaveToken = true;
option.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
builder.Services.AddTransient<ITokenService, TokenService>();//注册TokenService实例
#endregion
需要特别注意的是,Program.cs管道中的Authentication和Authorization的顺序, Authentication 应始终放在Authorization 之前。
app.UseAuthentication();
app.UseAuthorization();
2.添加TokenService.cs
代码如下:
public interface ITokenService
{
string GenerateToken(User user);
}
public class TokenService : ITokenService
{
private readonly JwtSettings _jwtSettings;
private double _expires=24;
public TokenService(IOptions<JwtSettings> jwtSettings)
{
_jwtSettings = jwtSettings.Value;
}
public string GenerateToken(User user)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_jwtSettings.SecretKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id ?? "default".ToString()),
new Claim(ClaimTypes.Name, user.UserName ?? "default"),
new Claim(ClaimTypes.Role, user.Role??"default")//角色权限
// 添加其他自定义的Claims
}),
Expires = DateTime.UtcNow.AddHours(_jwtSettings.ExpirationHours==null?_expires: (double)_jwtSettings.ExpirationHours),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
3.添加接口并测试效果
创建UserController.cs,并添加如下代码
[Route("api/[controller]/[action]")]
public class UserController : Controller
{
private readonly ITokenService _tokenService;
public UserController(ITokenService tokenService)
{
_tokenService = tokenService;
}
[HttpPost]
public IActionResult Login(User model)
{
var res=_tokenService.GenerateToken(model);
var data = new
{
code = 200,
token = res
};
return Ok(data);
}
[HttpPost]
[Authorize(Roles = "admin")]
public IActionResult GetUserInfo()
{
var data = new
{
code = 200,
msg="成功"
};
return Ok(data);
}
}
接下来做一下测试,首先为Role不为admin的用户生成token
{
"code": 200,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxMjMiLCJ1bmlxdWVfbmFtZSI6IjEyMyIsInJvbGUiOiJkZWZhdWx0IiwibmJmIjoxNjkyOTQ4NjEwLCJleHAiOjE2OTMwMzUwMTAsImlhdCI6MTY5Mjk0ODYxMH0.jGvPZG6JMxzFOr5N56EFxsHt5ZN_pH4gskG6plKmFFY"
}
同理,为Role为admin的用户生成token
{
"code": 200,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxMjMiLCJ1bmlxdWVfbmFtZSI6IjEyMyIsInJvbGUiOiJhZG1pbiIsIm5iZiI6MTY5Mjk0ODc3OCwiZXhwIjoxNjkzMDM1MTc4LCJpYXQiOjE2OTI5NDg3Nzh9.oK0FK9D0lHOVIdWb8i09ZT8rJgoYwx5R3JS_3Yf3csU"
}
接下来可以分别拿着两个token尝试请求接口GetUserInfo
default:
admin:
可以看出,权限限制生效了
总结
上述示例提供了使用JWT进行身份验证和授权的基本流程。你可以根据实际需求进行进一步的开发和扩展,例如在登录请求中验证用户凭证、定义角色和策略来限制访问等。
请注意,在实际应用中,你可能还需要添加用户注册、密码加密、令牌刷新等功能,以及处理令牌过期和错误处理等方面的逻辑。