web-dev-qa-db-ja.com

JWT署名を検証するときのSecurityTokenSignatureKeyNotFoundException

組織にOpenIDConnect仕様を実装しようとしています。テストの証明書利用者アプリケーションでMicrosoftのOpenIDConnectのOWIN実装を使用して、プロトコルの実装を検証しています。

次のメタデータドキュメントを公開しました。

{
  "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"
    }
  ]
}

IDトークンは、 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 = False、Count = 1、Claus [0] = X509ThumbprintKeyIdentifierClause(Hash = 0xF8A59280B3D13777CC7541B3218480984F421450))'、トークン: '{"typ": "JWT"、 "alg": "RS256" "x5t": "-KWSgLPRN3fMdUGzIYSAmE9CFFA"}。{"iss": " https://test.accesscontrol.net/ "、 "aud": "test"、 "nbf":1404917162、 " EXP ":1404917462、" サブ ":" 60eb55ec-0699から4068-bfa6-41666fc2b2e9" 、 "IAT": "1404917162"}のRawData:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ii1LV1NnTFBSTjNmTWRVR3pJWVNBbUU5Q0ZGQSJ9.eyJpc3MiOiJodHRwczovL2Fjcy5zdXJlY2xvdWQuY29tLyIsImF1ZCI6InRlc3QiLCJuYmYiOjE0MDQ5MTcxNjIsImV4cCI6MTQwNDkxNzQ2Miwic3ViIjoiNjBlYjU1ZWMtMDY5OS00MDY4LWJmYTYtNDE2NjZmYzJiMmU5IiwiaWF0IjoiMTQwNDkxNzE2MiJ9.xkP0RwlX3CYfU0KhFsVvLJC94WK22DTqNTm71cfjiJ8VUHv3b2YhDqfq70N8mQEyiR8vTR6OQqnO6UqXqX4RXUs6ZkfK9Liv3n9NhCs97wJhP2jfefJYeScYtRmWcNNWSSL7vkm2JXQfwKOQTnOGp-ba04TtI6jVrjhOQXH43eCJ9vNuBUzdD-t8CAdmnbvH0nWpIB8kWbw5v8Sa0aQuxMjJYbLC_2Iw3X13dqnyVjp4fA7eSB8N7c1it0KEB-VKfUqiGD3VecyEZGGZbaGE8r vVet5QrY1lJ3V4yM8j6-xDc5Yndc4swOun0L3D6TYk-8gdVXUJDRjbv1ZuhZltsw '。

コンポーネントはまだプレリリースであるため、これは実装の欠陥である可能性がありますが、すべての可能性が排除されるまでは私のエラーであると想定したいと思います。

明らかに間違っていることはありますか、それとも署名が検証されない理由を正確に理解するためにすべきことはありますか?

11
Paul Turner

この問題は、次の例外メッセージに含まれています。

Clause [0] = X509ThumbprintKeyIdentifierClause(Hash = 0xF8A59280B3D13777CC7541B3218480984F421450)

トークンは、X.509証明書のデフォルトのキー識別子句である拇印で署名されています。メタデータは、RSAパラメーターと名前識別子のみを公開しています。クライアントがメタデータを取得すると、X.509拇印ではなく、この情報を使用してRSAキーが設定されます。

このエラーを修正するには、署名資格情報を変更して、正しい名前識別子を含める必要があります。

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

これには、署名に予期される識別子が含まれ、署名は正常に検証されます。

7
Paul Turner