2014-07-09 51 views
10

我正在嘗試爲我的組織實施OpenID Connect規範。我在測試依賴方應用程序中使用Microsoft的OWIN OpenID Connect實現來驗證我的協議實現。驗證JWT簽名時出現SecurityTokenSignatureKeyNotFoundException

我露出下面的元數據文檔:

{ 
    "issuer": "https://acs.contoso.com/", 
    "authorization_endpoint": "http://localhost:53615/oauth2/auth", 
    "token_endpoint": "http://localhost:53615/oauth2/token", 
    "userinfo_endpoint": "http://localhost:53615/connect/userinfo", 
    "jwks_uri": "http://localhost:53615/connect/keys", 
    "ui_locales_supported": [ 
    "en-GB" 
    ] 
} 

簽名密鑰被暴露在本文件:

{ 
    "keys": [ 
    { 
     "n": "xpXxl3M-YkZlzQJdArO1TfOGT2no-UL4dbZ7WuSCNIsSfyGDaqUXjMMHNyq9yD3vp-NCyk8kmn7d5XqHufnceXJM8q4xTrhN3lvywdBSbR-dwXsA-B-MJVgfiK0d_z-mxP9ew2Hj9-KkWbWCzsswlWp3gZ4mB4RGutB1IRSzXVIbvZ-MtKUb6XUDU4LDb_c1xCEXWZxhR-o1a1dLfObH2hHJ-w5y6odGlKtOFx4i4h0u7-Oj5R6k5b2YXEHM0IuYeN0u0sQvrTecokntGzPrvhnKy69I7Z_az5rC5kgloh25D9lTbe4vcRU7FXlYCFYDZsT0_IkGIXRi7brOS4f1ow", 
     "e": "AQAB", 
     "kty": "RSA", 
     "use": "sig", 
     "alg": "RS256", 
     "kid": "F8A59280B3D13777CC7541B3218480984F421450" 
    } 
    ] 
} 

正在使用JwtSecurityToken類及其關聯的處理產生的身份令牌,使用X509SigningCredentials類。此代碼表示令牌如何構造並作爲響應數據的參數返回給調用系統。

var credentials = new X509SigningCredentials(cert); // My certificate. 
var issuedTime = DateTime.UtcNow; 
var expiresTime = issuedTime.AddMinutes(5); 
var epoch = new DateTime(1970, 01, 01, 0, 0, 0); 

var claims = new[] 
{ 
    new Claim("sub", Guid.NewGuid().ToString()), 
    new Claim("iat" Math.Floor((issuedTime - epoch).TotalSeconds).ToString()), 
    new Claim("nonce", nonce), // Value from client 
} 

var token = new JwtSecurityToken(
    "https://acs.contoso.com", 
    client_id, // Value from client 
    claims, 
    new Lifetime(issuedTime, expiresTime), 
    credentials); 

var handler = new JwtSecurityTokenHandler(); 
parameters.Add("id_token", handler.WriteToken(token)); // Outgoing parameters. 

當我嘗試簽名令牌回傳給了依賴方應用程序時,OWIN中間件接受POST和嘗試驗證令牌的簽名。這樣做會引發以下異常:

SecurityTokenSignatureKeyNotFoundException:IDX10500:簽名 驗證失敗。無法解析SecurityKeyIdentifier: 'SecurityKeyIdentifier(IsReadOnly =假,計數= 1,第[0] = X509ThumbprintKeyIdentifierClause(散列= 0xF8A59280B3D13777CC7541B3218480984F421450))',令牌: 「{ 「典型值」: 「JWT」, 「ALG」: 「RS256」,「x5t」:「 - KWSgLPRN3fMdUGzIYSAmE9CFFA」}。{「iss」:「https://test.accesscontrol.net/」,「aud」:「test」,「nbf」:1404917162,「exp」:1404917462,「sub」:「60eb55ec- 0699-4068-bfa6-41666fc2b2e9" , 「IAT」: 「1404917162」} RAWDATA: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ii1LV1NnTFBSTjNmTWRVR3pJWVNBbUU5Q0ZGQSJ9.eyJpc3MiOiJodHRwczovL2Fjcy5zdXJlY2xvdWQuY29tLyIsImF1ZCI6InRlc3QiLCJuYmYiOjE0MDQ5MTcxNjIsImV4cCI6MTQwNDkxNzQ2Miwic3ViIjoiNjBlYjU1ZWMtMDY5OS00MDY4LWJmYTYtNDE2NjZmYzJiMmU5IiwiaWF0IjoiMTQwNDkxNzE2MiJ9.xkP0RwlX3CYfU0KhFsVvLJC94WK22DTqNTm71cfjiJ8VUHv3b2YhDqfq70N8mQEyiR8vTR6OQqnO6UqXqX4RXUs6ZkfK 9Liv3n9NhCs97wJhP2jfefJYeScYtRmWcNNWSSL7vkm2JXQfwKOQTnOGp-ba04TtI6jVrjhOQXH43eCJ9vNuBUzdD-t8CAdmnbvH0nWpIB8kWbw5v8Sa0aQuxMjJYbLC_2Iw3X13dqnyVjp4fA7eSB8N7c1it0KEB-VKfUqiGD3VecyEZGGZbaGE8rvVet5QrY1lJ3V4yM8j6-xDc5Yndc4swOun0L3D6TYk-8gdVXUJDRjbv1ZuhZltsw」。

該組件仍然是預發佈的,所以這可能是實現中的缺陷,但是我想假設這是我的錯誤,直到排除所有可能性。

有什麼我正在做的事顯然是錯的,或者有什麼我應該做的以明確爲什麼簽名無法驗證?

回答

5

問題坐落在異常的訊息:

第[0] = X509ThumbprintKeyIdentifierClause(散列= 0xF8A59280B3D13777CC7541B3218480984F421450)

該令牌與默認密鑰標識符子句簽署用於X .509證書:指紋。元數據僅公開RSA參數和名稱標識符。當客戶端檢索元數據時,它使用此信息設置RSA密鑰,而不是X.509指紋。

要糾正這個錯誤,簽名證書必須改變,以包括正確的名稱標識符:

var credentials = new X509CertificateCredentials(
    cert, 
    new SecurityKeyIdentifier(
     new NamedKeySecurityKeyIdentifierClause(
      "kid", 
      "F8A59280B3D13777CC7541B3218480984F421450"))); 

這包括簽名預期的標識符,並且簽名驗證成功。

+1

請告訴我在哪裏可以得到您所指的證書? –

+1

這很有道理,但是你從哪裏獲得證書? –

+0

我正在學習一個教程,並且使用臨時證書'AddTemporarySigningCredential()',所以在刷新Web應用程序之後,它就可以工作。 – Jaider