2013-08-03 36 views
14

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ỉ?

Trả lời

6

Bạn phải hiển thị khóa công khai mà bạn có thể nhận được bằng cách nhấp chuột phải vào chứng chỉ và thực hiện Xuất (không bao gồm khóa riêng) trên MMC. Sau đó, bất kỳ ai phải xác thực mã thông báo sẽ làm

var x509 = new X509Certiicate2(pathToExportedCert); 

Hoặc bạn cũng có thể sử dụng ctor mảng byte và khóa công khai được mã hóa trong base64.

+0

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

+0

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

Các vấn đề liên quan