net.core webapi 使用JWT生成token与验证
1、添加服务(Nuget 安装 )
Microsoft.AspNetCore.Authentication.JwtBearer
2.注意: 不要在nuget中安装 Microsoft.IdentityModel.Tokens 包, 直接suing 引用就有, 否则就会报401错误
3. 在 Program.cs 文件配置如下
//添加JWT身份验证服务
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否效验Issuer
ValidateAudience = true,//是否效验Audience
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否效验SigningKey
ValidIssuer = TokenParameter.Issuer,//颁发者
ValidAudience = TokenParameter.Audience,//接收者
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenParameter.Secret))
};
});
//配置Swagger身份验证输入(可选)
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "请输入token,格式为 【Bearer JWT字符串】(注意中间必须有空格)",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = "Bearer"
});
//添加安全要求
options.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme{
Reference =new OpenApiReference{
Type = ReferenceType.SecurityScheme,
Id ="Bearer"
}
},new string[]{ }
}
});
});
4. 在Program.cs 文件使用中间件
app.UseAuthentication();
app.UseAuthorization();
5. 创建帮助类 JwtHelper.cs
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace WebApplication1
{
public class JwtHelper
{
public static string GenerateJsonWebToken(LoginParams userInfo)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenParameter.Secret));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claimsIdentity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
claimsIdentity.AddClaim(new Claim("ID", "1001"));
claimsIdentity.AddClaim(new Claim("Username", userInfo.username));
claimsIdentity.AddClaim(new Claim("Password", userInfo.password));
claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, "龙卷风摧毁停车场")); //设置用户名
claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "admin")); //设置用户角色
//可通过如下方式来获取用户名或用户角色
//bool isInRole = HttpContext.User.IsInRole("admin");// 检查用户是否属于某个角色
//string username = HttpContext.User.Identity.Name; //获取用户名
var token = new JwtSecurityToken(
issuer: TokenParameter.Issuer,
audience: TokenParameter.Audience,
claims: claimsIdentity.Claims,
expires: DateTime.Now.AddMinutes(TokenParameter.AccessExpiration),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
/// <summary>
/// 建议将TokenParameter类配置到appsettings.json中
/// </summary>
public class TokenParameter
{
public const string Issuer = "Authentication:Issuer";//颁发者
public const string Audience = "Authentication:Audience";//接收者
public const string Secret = "bKgEeQFTs7dMgPJ532LehCXBRbI+LfTU0uNtZFHs5OE=";//签名秘钥
public const int AccessExpiration = 30;//AccessToken过期时间(分钟)
}
/// <summary>
/// LoginParams类也建议提到其它文件中
/// </summary>
public class LoginParams
{
public string username { get; set; }
public string password { get; set; }
}
}
}
6 .签名秘钥使用 RNGCryptoServiceProvider 类来生成随机的字节数组,然后将其转换为Base64编码的字符串作为JWT的秘钥。(具体怎么创建点击: https://www.cnblogs.com/tlfe/p/18230656 滑动到最底部)
7. 创建 AuthController.cs 接口
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using WebApplication1;
namespace WebApplication2.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class AuthController : ControllerBase
{
[HttpPost]
public ActionResult GetToken(LoginParams user)
{
if (user.UserName == "admin" && user.UserPwd == "123456")
{
string token = JwtHelper.GenerateJsonWebToken(user);
return Ok("Bearer "+token); //需要再token前面加上Bearer
}
Dictionary<string, object> data = new Dictionary<string, object>();
data["code"] = 2;
data["msg"] = "帐号或密码错误";
return Ok(data);
}
}
}
8. 创建验证token接口 TestController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
namespace WebApplication2.Controllers
{
[Route("api/[controller]/[Action]")]
[ApiController]
public class TestController : ControllerBase
{
[Authorize(Roles = "admin")] //只有admin角色才可以访问此接口
[HttpPost]
public string GetTestInfo()
{
return "验证成功";
}
}
}