net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)八使用pfx证书RSA方式生成jwt签名的Token,公钥验证签名
Posted 圆滚滚的胖狸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)八使用pfx证书RSA方式生成jwt签名的Token,公钥验证签名相关的知识,希望对你有一定的参考价值。
关于JWT引用的补充
因为Ids5收费的缘故,因此原本打算引用ids的想法被放弃了。只能自己来实现了
生产环境下,肯定需要用证书来产生Token,所以我们先生成证书
本机安装openssl,然后打开openssl带的控制台,
在openssl 控制台中顺序执行以下命令
具体命令的含义请自行百度
// 进入到准备好的证书文件夹
cd F:\\NET6Demo_WebApi\\NET6Demo_WebApi\\Certificate
// 生成私钥key文件
openssl genrsa -out xxx_rsa_aes_private.key 2048
// 生成公钥key文件
openssl rsa -in xxx_rsa_aes_private.key -pubout -out xxx_rsa_public.key
// 生成crt文件
openssl req -new -x509 -days 3650 -key xxx_rsa_aes_private.key -out xxx_cert.crt
// 生成pfx文件 需要设置证书密码
openssl pkcs12 -export -in xxx_cert.crt -inkey xxx_rsa_aes_private.key -out xxx.pfx
// 生成cer文件
openssl pkcs12 -nodes -nokeys -in xxx.pfx -passin pass:证书密码 -nokeys -out xxx.cer
回到vs2022 项目中来,可以看到添加后的证书文件
记得要设置文件属性
然后,修改appsetting.json文件,添加"Certificates",修改:"JWT"
"Certificates":
"CertPath": "Certificate\\\\xxx.pfx",
"Password": "CdPX05TW8rNiq2IE",
"PublicCert": "Certificate\\\\xxx.cer"
,
"JWT":
"Issuer": "com.xxx.authService",
"Audience": "oauth/com.xxx.authService",
"Expires": "7200"
,
接下来我们对jwt部分进行改造
修改JwtHelper.cs的CreateJwtToken方法
using CommonCode.Converts;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
namespace CommonCode.JWT
/// <summary>
/// 单例
/// 用于产生Token和验证Token
/// </summary>
public class JwtHelper
private readonly static JwtSecurityTokenHandler _jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
/// <summary>
/// 创建加密JwtToken
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public static string CreateJwtToken<T, U>(in T user,in U jwt, string certPath, string certPassword) //修改了此方法
IJwtModel jwtModel = ConvertTo.ConvertModel<U, JwtModel>(jwt);
var claimList = CreateClaimList<T>(user);
// 这一句会产生500错误
//var algorithm = signingKey.PrivateKey.SignatureAlgorithm;
// 选择加密算法
var algorithm = SecurityAlgorithms.RsaSha256;
// 加载pfx证书
X509Certificate2 authCert = new X509Certificate2(certPath, certPassword);
X509SecurityKey signingKey = new X509SecurityKey(authCert);
// 生成Credentials
//var signingCredentials = new SigningCredentials(signingKey, "RS256");
var signingCredentials = new SigningCredentials(signingKey, algorithm);
JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
jwtModel.Issuer, //Issuer
jwtModel.Audience, //Audience
claims: claimList,
DateTime.Now, //notBefore
DateTime.Now.AddSeconds(jwtModel.Expires), //expires
signingCredentials //Credentials
);
string jwtToken = _jwtSecurityTokenHandler.WriteToken(jwtSecurityToken);
return jwtToken;
public static T GetToken<T>(string Token)
Type t = typeof(T);
object objA = Activator.CreateInstance(t);
var b = _jwtSecurityTokenHandler.ReadJwtToken(Token);
foreach (var item in b.Claims)
PropertyInfo _Property = t.GetProperty(item.Type);
if (_Property != null && _Property.CanRead)
_Property.SetValue(objA, item.Value, null);
return (T)objA;
/// <summary>
/// 创建包含用户信息的CalimList
/// </summary>
/// <param name="authUser"></param>
/// <returns></returns>
private static List<Claim> CreateClaimList<T>(T authUser)
var Class = typeof(T);
List<Claim> claimList = new List<Claim>();
foreach (var item in Class.GetProperties())
claimList.Add(new Claim(item.Name, Convert.ToString(item.GetValue(authUser))));
return claimList;
修改Tokenhelper.cs
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using NET6Demo.IRepository;
using CommonCode.JWT;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using CommonCode.Helper;
namespace NET6Demo.Utility.Token
public class TokenHelper
private readonly IConfiguration _configuration;
private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler;
private readonly ILogger<TokenHelper> _logger;
private ITokenModel _tokenModel;
private IUserInfo _user;
public TokenHelper(
IConfiguration configuration,
JwtSecurityTokenHandler jwtSecurityTokenHandler,
ILogger<TokenHelper> logger,
ITokenModel tokenModel
//IUserInfo user
)
_configuration = configuration;
_jwtSecurityTokenHandler = jwtSecurityTokenHandler;
_logger = logger;
_tokenModel = tokenModel;
// _user = user;
private static string basePath = AppContext.BaseDirectory; //添加
// <summary>
/// 创建加密JwtToken
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public string CreateJwtToken(IUserInfo user) //修改
// 从 appsettings.json 中读取配置,采取pfx证书
//var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:SecretKey"]));
var certPath = Path.Combine(basePath, AppsettingHelper.Get("Certificates:CertPath"));
var certPassowrd = AppsettingHelper.Get("Certificates:Password");
_tokenModel.Issuer = AppsettingHelper.Get("JWT:Issuer");
_tokenModel.Audience = AppsettingHelper.Get("JWT:Audience");
//需要从数据库中读取
_tokenModel.Expires = Convert.ToDouble(_configuration["JWT:Expires"]);
return JwtHelper.CreateJwtToken(_user, _tokenModel, certPath, certPassowrd);
public IUserInfo GetToken(string Token)
return JwtHelper.GetToken<IUserInfo>(Token);
public bool VerTokenAsync(string Token)
return true;
修改program.cs 中关于jwt的部分
#region 添加身份验证JWT
builder.Services.AddSingleton<
IAuthorizationMiddlewareResultHandler, Net6DemoAuthorizationMiddleware>();
//添加jwt验证:
var publicCert = new X509Certificate2(Path.Combine(basePath, builder.Configuration["Certificates:PublicCert"]));
var publicKey = new X509SecurityKey(publicCert);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters()
ValidateIssuer = true,
ValidIssuer = builder.Configuration["JWT:Issuer"],
ValidateAudience = true,
ValidAudience = builder.Configuration["JWT:Audience"],
ValidateLifetime = true,
IssuerSigningKey = publicKey,
;
);
#endregion
修改一下Net6DemoAuthorizationMiddleware
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Http;
namespace NET6Demo.Utility.Authorize
public class Net6DemoAuthorizationMiddleware : IAuthorizationMiddlewareResultHandler
private readonly AuthorizationMiddlewareResultHandler defaultHandler = new();
public async Task HandleAsync(
RequestDelegate next,
HttpContext context,
AuthorizationPolicy policy,
PolicyAuthorizationResult authorizeResult)
if(!authorizeResult.Succeeded) //添加成功判断
if (authorizeResult.Forbidden
&& authorizeResult.AuthorizationFailure!.FailedRequirements
.OfType<Show404Requirement>().Any())
// Return a 404 to make it appear as if the resource doesn't exist.
throw new KeyNotFoundException();
throw new ApplicationException("Invalid token");
public class Show404Requirement : IAuthorizationRequirement
在controller修改GetTestResult,添加TestToken
[AllowAnonymous]
[HttpGet("GetTest")]
public async Task<IActionResult> GetTestResult(string userId)
Console.WriteLine("测试一下输出日志");
_logger.LogInformation("日志输出了");
_user = _provider.GetService<IUsers>().GetUser(userId);
return Ok(_tokenHelper.CreateJwtToken(_user));
[Authorize]
[HttpGet("TestToken")]
public async Task<IActionResult> TestToken()
Console.WriteLine("输出日志 TestToken");
_logger.LogInformation("TestToken");
return Ok();
另外,这次对AppsettingHelper文件有了小小的修改
using Microsoft.Extensions.Configuration;
namespace CommonCode.Helper
public class AppsettingHelper
//private static IConfiguration _config;
//private static string _basePath;
//public AppsettingHelper(IConfiguration config)
//
// _config = config;
// _basePath = AppContext.BaseDirectory;
//
public static string? Get(string key)
var config = getConfigContainer();
return config[key];
/// <summary>
/// 读取实体信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="session"></param>
/// <returns></returns>
public static List<T> Get<T>(params string[] session)
List<T> list = new List<T>();
var config = getConfigContainer();
config.Bind(string.Join(":", session), list);
return list;
private static IConfiguration getConfigContainer()
var basePath = AppContext.BaseDirectory;
//引用Microsoft.Extensions.Configuration;
var Configuration = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("appsettings.json")
.AddJsonFile("appsettings.test.json", true, reloadOnChange: true);
var config = Configuration.Build();
return config;
//要记得注销掉program.cs中的相关代码
//builder.Services.AddSingleton(new CommonCode.Helper.AppsettingHelper(config));
运行代码,在swagger中获取到token
注意:因为我多次运行,所以截图中的Token可能会不一样,不影响程序本身的运行结果
验证在swager进行
在postman中验证
以上是关于net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)八使用pfx证书RSA方式生成jwt签名的Token,公钥验证签名的主要内容,如果未能解决你的问题,请参考以下文章
net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)二配置log4net
net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)六添加身份验证,引入JWT
net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)六添加身份验证,引入JWT
net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)六添加身份验证,引入JWT
net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)一建立项目,使用Swagger
net6 项目搭建及引用框架记录(log4net,autofac,exception,api result,jwt,efcore)一建立项目,使用Swagger