2013-08-03 78 views
14

我設法使JwtSecurityTokenHandlerX509Certificate2一起工作。我能夠用X509Certificate2對象簽署該令牌。我也可以通過X509Certificate2.RawData屬性使用證書的原始數據來驗證令牌。用X509Certificate2保護JWT(JwtSecurityTokenHandler)

下面是代碼:

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

我的主要問題是什麼一回事,我應該從我X509Certificate2暴露給世界。我應該透露哪一部分X509Certificate2,以便消費者應驗證JWT令牌,但不能使用相同證書創建新令牌

回答

6

您必須公開您通過右鍵單擊證書獲得的公鑰並在MMC上執行導出(不包括私鑰)。然後,誰就擁有驗證令牌會做

var x509 = new X509Certiicate2(pathToExportedCert); 

或者你也可以使用字節數組構造函數並在base64編碼的公共密鑰。

+0

謝謝!我正在考慮公開'X509Certiicate2.RawData',我假設它不包含私鑰。我對嗎?當我通過傳遞另一個證書的RawDate構造一個新的X509Certiicate2對象時,我沒有看到新證書有一個私鑰(我認爲)用於簽署該令牌。 – tugberk

+0

是的。 'RawData'是base64編碼的X509證書數據。這相當於如此處所示導出證書![](http://puu.sh/3SFr4.png)。不同之處在於RawData將不包含'---- BEGIN/END CERT ...'標題並且不包含crlf。順便說一下你的用例是什麼?如果你想要跨平臺的東西,我會建議給消費者提供編碼的證書,包括標題和crlf。 – woloski