下面是关于“ASP.NET Core应用JWT进行用户认证及Token的刷新方案”的完整攻略,包含两个示例说明。
简介
JWT(JSON Web Token)是一种用于身份验证的开放标准,它可以在客户端和服务器之间安全地传输信息。在ASP.NET Core中,我们可以使用JWT来进行用户认证,并实现Token的刷新。本文将详细讲解如何在ASP.NET Core应用中使用JWT进行用户认证及Token的刷新方案。
用户认证及Token的刷新方案
以下是在ASP.NET Core应用中使用JWT进行用户认证及Token的刷新方案的步骤:
- 在ASP.NET Core应用中安装Microsoft.AspNetCore.Authentication.JwtBearer NuGet包:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
在上面的命令中,我们使用dotnet命令来安装Microsoft.AspNetCore.Authentication.JwtBearer NuGet包。
- 在appsettings.json文件中添加JWT配置:
{
"Jwt": {
"Issuer": "YourIssuer",
"Audience": "YourAudience",
"Key": "YourKey",
"ExpireMinutes": 60,
"RefreshExpireMinutes": 1440
}
}
在上面的代码中,我们添加了JWT的配置信息,包括Issuer、Audience、Key、ExpireMinutes和RefreshExpireMinutes等。
- 在Startup.cs文件中添加JWT认证服务:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
public void ConfigureServices(IServiceCollection services)
{
// ...
var jwtSettings = Configuration.GetSection("Jwt");
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"]));
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = key
};
});
// ...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
app.UseAuthentication();
app.UseAuthorization();
// ...
}
在上面的代码中,我们添加了JWT认证服务,并配置了TokenValidationParameters。
- 在AccountController中添加登录和刷新Token的API接口:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
[ApiController]
[Route("[controller]")]
public class AccountController : ControllerBase
{
private readonly IConfiguration _configuration;
public AccountController(IConfiguration configuration)
{
_configuration = configuration;
}
[AllowAnonymous]
[HttpPost("login")]
public IActionResult Login([FromBody] LoginModel model)
{
if (model == null)
{
return BadRequest("Invalid client request");
}
if (model.Username == "admin" && model.Password == "admin")
{
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
var signingCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, model.Username),
new Claim(ClaimTypes.Role, "Admin")
};
var tokenOptions = new JwtSecurityToken(
issuer: _configuration["Jwt:Issuer"],
audience: _configuration["Jwt:Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(Convert.ToDouble(_configuration["Jwt:ExpireMinutes"])),
signingCredentials: signingCredentials
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
return Ok(new { Token = tokenString });
}
else
{
return Unauthorized();
}
}
[AllowAnonymous]
[HttpPost("refresh")]
public IActionResult Refresh([FromBody] RefreshTokenModel model)
{
if (model == null)
{
return BadRequest("Invalid client request");
}
var principal = GetPrincipalFromExpiredToken(model.Token);
var username = principal.Identity.Name; //this is mapped to the Name claim by default
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
var signingCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, "Admin")
};
var tokenOptions = new JwtSecurityToken(
issuer: _configuration["Jwt:Issuer"],
audience: _configuration["Jwt:Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(Convert.ToDouble(_configuration["Jwt:ExpireMinutes"])),
signingCredentials: signingCredentials
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
return Ok(new { Token = tokenString });
}
private ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
{
var tokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"])),
ValidateLifetime = false //here we are saying that we don't care about the token's expiration date
};
var tokenHandler = new JwtSecurityTokenHandler();
SecurityToken securityToken;
var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out securityToken);
var jwtSecurityToken = securityToken as JwtSecurityToken;
if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
{
throw new SecurityTokenException("Invalid token");
}
return principal;
}
}
public class LoginModel
{
public string Username { get; set; }
public string Password { get; set; }
}
public class RefreshTokenModel
{
public string Token { get; set; }
}
在上面的代码中,我们添加了Login和Refresh API接口,用于用户登录和Token的刷新。
- 在Startup.cs文件中添加Swagger UI:
using Microsoft.OpenApi.Models;
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
// ...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
// ...
}
在上面的代码中,我们添加了Swagger UI,用于测试API接口。
- 启动应用程序,并使用Postman等工具测试API接口。
示例说明
以下是两个示例说明,演示如何在ASP.NET Core应用中使用JWT进行用户认证及Token的刷新:
示例1:用户登录
使用Postman向"http://localhost:5000/account/login"发送POST请求,请求体中包含用户名和密码,即可获取Token。
示例2:Token刷新
使用Postman向"http://localhost:5000/account/refresh"发送POST请求,请求体中包含过期的Token,即可获取新的Token。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ASP.NET Core应用JWT进行用户认证及Token的刷新方案 - Python技术站