2013-08-03 10 views
14

Ich schaffte es, die JwtSecurityTokenHandler arbeiten mit X509Certificate2. Ich konnte den Token mit einem X509Certificate2 Objekt signieren. Ich war auch in der Lage, das Token zu validieren, indem ich die Rohdaten des Zertifikats über die Eigenschaft X509Certificate2.RawData verwendete. HierSicherung der JWT mit einem X509Certificate2 (JwtSecurityTokenHandler)

ist der Code:

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; 
    } 
} 

Meine Hauptfrage dreht sich alles um, was soll ich in die Welt von meinem X509Certificate2 aussetzen. Welchen Teil des X509Certificate2 sollte ich offenlegen, so dass der Verbraucher das JWT-Token validieren sollte, aber kann kein neues Token mit dem gleichen Zertifikat erstellen?

Antwort

6

Sie müssen den öffentlichen Schlüssel verfügbar machen, den Sie erhalten, indem Sie mit der rechten Maustaste auf das Zertifikat klicken und Export (nicht den privaten Schlüssel) auf der MMC ausführen. Dann hat jeder, der Token tun würde zu validieren

var x509 = new X509Certiicate2(pathToExportedCert); 

Oder Sie können auch das Byte-Array Ctor verwenden und den öffentlichen Schlüssel in Base64 codiert.

+0

danke! Ich dachte daran, das 'X509Certiicate2.RawData' zu enthüllen und nehme an, dass es den privaten Schlüssel nicht enthält. habe ich recht? Wenn ich ein neues X509Certiicate2-Objekt konstruiere, indem ich das RawDate eines anderen Zertifikats übergebe, sehe ich nicht, dass das neue Zertifikat einen privaten Schlüssel hat, von dem (wie ich annehme) das Token signiert wird. – tugberk

+0

Ja. 'RawData' sind die X509-Cert-Daten, die in base64 codiert sind. Es entspricht dem Export des Zertifikats wie hier gezeigt! [] (Http://puu.sh/3SFr4.png). Der Unterschied ist, dass RawData nicht die Header '---- BEGIN/END CERT ...' und keine crlf enthält. Was ist übrigens dein Anwendungsfall? Wenn Sie etwas wollen, das plattformübergreifend funktioniert, würde ich vorschlagen, den Verbrauchern das cert coded einschließlich dieser Header und crlf zu geben. – woloski