C#不能使用证书签名JWT
问题描述:
我正在使用VS 2017和.NET 4.6.2开发C#Web Api MVC项目,我想用我的证书签署JSON Web令牌。C#不能使用证书签名JWT
这是我的代码:
using SolutionDOC_Common;
using SolutionDOC_Interface.Repository.Authentication;
using SolutionDOC_SDK.Model;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Authentication;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using mit = Microsoft.IdentityModel.Tokens;
public string Build(Credentials credentials)
{
string thumbprint = ConfigurationManager.AppSettings["CertificateThumbprint"];
string tokenIssuer = ConfigurationManager.AppSettings["TokenIssuer"];
string tokenAudience = ConfigurationManager.AppSettings["TokenAudience"];
List<Claim> claims = new List<Claim>
{
new Claim(ClaimTypes.Name, credentials.Username),
new Claim(ClaimTypes.Surname, credentials.Alias)
};
X509Certificate2 cert = CertificateUtility.GetCertificateByThumbprint(thumbprint);
RSACryptoServiceProvider publicAndPrivate = (RSACryptoServiceProvider)cert.PublicKey.Key;
JwtSecurityToken jwtToken = new JwtSecurityToken
(
issuer: tokenIssuer,
audience: tokenAudience,
claims: claims,
signingCredentials: new mit.SigningCredentials(new mit.RsaSecurityKey(publicAndPrivate), mit.SecurityAlgorithms.RsaSha256Signature),
expires: DateTime.Now.AddDays(30)
);
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
// This throws the InvalidOperationException!
string tokenString = tokenHandler.WriteToken(jwtToken);
return tokenString;
throw new AuthenticationException();
}
的tokenHandler.WriteToken(jwtToken)
线,抛出一个InvalidOperationException
说
“IDX10638:无法创建SignatureProvider, 'key.HasPrivateKey' 是假的,不能创建签名。键:Microsoft.IdentityModel.Tokens.RsaSecurityKey。'
相应证书的权限设置为IIS_IUSRS用户,因此它也可以读取私钥。该证书实际上是一个使用IIS生成的自签名证书,该证书具有私钥。 拇指指纹设置正确,所以我得到正确的证书。 所以我正确地得到了X509Certificate2
对象。 X509Certificate2
对象的PrivateKey属性已填充。
它为什么不起作用?
答
那么,即使您标记了变量publicAndPrivate
,您显然只能提取公钥。试试
RSACryptoServiceProvider publicAndPrivate = (RSACryptoServiceProvider)cert.PrivateKey;