Tôi đã quản lý để làm cho JwtSecurityTokenHandler
hoạt động với X509Certificate2
. Tôi đã có thể ký mã thông báo với đối tượng X509Certificate2
. Tôi cũng có thể xác thực mã thông báo bằng cách sử dụng dữ liệu thô của chứng chỉ qua thuộc tính X509Certificate2.RawData
.Bảo vệ JWT bằng X509Certificate2 (JwtSecurityTokenHandler)
Đây là mã:
class Program
{
static void Main(string[] args)
{
X509Store store = new X509Store("My");
store.Open(OpenFlags.ReadOnly);
X509Certificate2 signingCert = store.Certificates[0];
string token = CreateTokenWithX509SigningCredentials(signingCert);
ClaimsPrincipal principal = ValidateTokenWithX509SecurityToken(
new X509RawDataKeyIdentifierClause(signingCert.RawData), token);
}
static string CreateTokenWithX509SigningCredentials(X509Certificate2 signingCert)
{
var now = DateTime.UtcNow;
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, "Tugberk"),
new Claim(ClaimTypes.Role, "Sales"),
}),
TokenIssuerName = "self",
AppliesToAddress = "http://www.example.com",
Lifetime = new Lifetime(now, now.AddMinutes(2)),
SigningCredentials = new X509SigningCredentials(signingCert)
};
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);
string tokenString = tokenHandler.WriteToken(token);
return tokenString;
}
static ClaimsPrincipal ValidateTokenWithX509SecurityToken(X509RawDataKeyIdentifierClause x509DataClause, string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
var x509SecurityToken = new X509SecurityToken(new X509Certificate2(x509DataClause.GetX509RawData()));
var validationParameters = new TokenValidationParameters()
{
AllowedAudience = "http://www.example.com",
SigningToken = x509SecurityToken,
ValidIssuer = "self",
};
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(
new JwtSecurityToken(token), validationParameters);
return claimsPrincipal;
}
}
câu hỏi chính của tôi là tất cả về những gì tôi nên tiếp xúc với thế giới từ X509Certificate2
tôi. Tôi nên tiết lộ phần nào của X509Certificate2 để người tiêu dùng nên xác thực mã thông báo JWT nhưng không thể tạo mã thông báo mới sử dụng cùng một chứng chỉ?
cảm ơn! Tôi đã suy nghĩ để lộ 'X509Certiicate2.RawData' và tôi cho rằng nó không bao gồm khóa riêng. tôi có đúng không khi tôi xây dựng một đối tượng X509Certiicate2 mới bằng cách chuyển một RawDate của chứng chỉ khác, tôi không thấy rằng chứng chỉ mới có khóa riêng (mà tôi giả định) được sử dụng để ký mã thông báo. – tugberk
Có. 'RawData' là dữ liệu cert X509 được mã hóa trong base64. Nó tương đương với việc xuất chứng chỉ như được hiển thị ở đây! [] (Http://puu.sh/3SFr4.png). Sự khác biệt là RawData sẽ không bao gồm tiêu đề '---- BEGIN/END CERT ...' và không có crlf. Trường hợp sử dụng của bạn là gì? Nếu bạn muốn một cái gì đó mà làm việc trên nền tảng, tôi sẽ đề nghị cho người tiêu dùng các cert mã hóa bao gồm cả những tiêu đề và crlf. – woloski