验证JWT签名时出现SecurityTokenSignatureKeyNotFoundException [英] SecurityTokenSignatureKeyNotFoundException when validating JWT signature

查看:1204
本文介绍了验证JWT签名时出现SecurityTokenSignatureKeyNotFoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的组织实施OpenID Connect规范.我在测试依赖方应用程序中使用Microsoft的OpenID Connect的OWIN实现来验证我对协议的实现.

I'm trying to implement the OpenID Connect specification for my organisation. I'm using Microsoft's OWIN implementation of OpenID Connect in a test relying party application to verify my implementation of the protocol.

我公开了以下元数据文档:

I've exposed the following metadata document:

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

签名密钥作为此文档公开:

The signing key is exposed as this document:

{
  "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类.该代码代表令牌的构造方式,并将其作为响应数据的参数返回给调用系统.

The identity token is being generated using the JwtSecurityToken class and its associated handler, using the X509SigningCredentials class. This code is representative of how the token is constructed and returned to the calling system as a parameter of the response data.

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并尝试验证令牌的签名.这样做会引发以下异常:

When I attempt to pass the signed token back to the relying party application, the OWIN middleware accepts the POST and attempts to verify the signature of the token. In doing so, the following exception is thrown:

SecurityTokenSignatureKeyNotFoundException:IDX10500:签名 验证失败.无法解析SecurityKeyIdentifier: 'SecurityKeyIdentifier(IsReadOnly = False,Count = 1,Clause [0] = X509ThumbprintKeyIdentifierClause(哈希= 0xF8A59280B3D13777CC7541B3218480984F421450))',令牌: '{"typ":"JWT","alg":"RS256","x5t":-KWSgLPRN3fMdUGzIYSAmE9CFFA"}.{"iss":" https://test.accesscontrol.net/," aud:" test," nbf:1404917162," exp:1404917462," sub:" 60eb55ec- 0699-4068-bfa6-41666fc2b2e9," iat:" 1404917162} 原始数据: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ii1LV1NnTFBSTjNmTWRVR3pJWVNBbUU5Q0ZGQSJ9.eyJpc3MiOiJodHRwczovL2Fjcy5zdXJlY2xvdWQuY29tLyIsImF1ZCI6InRlc3QiLCJuYmYiOjE0MDQ5MTcxNjIsImV4cCI6MTQwNDkxNzQ2Miwic3ViIjoiNjBlYjU1ZWMtMDY5OS00MDY4LWJmYTYtNDE2NjZmYzJiMmU5IiwiaWF0IjoiMTQwNDkxNzE2MiJ9.xkP0RwlX3CYfU0KhFsVvLJC94WK22DTqNTm71cfjiJ8VUHv3b2YhDqfq70N8mQEyiR8vTR6OQqnO6UqXqX4RXUs6ZkfK9Liv3n9NhCs97wJhP2jfefJYeScYtRmWcNNWSSL7vkm2JXQfwKOQTnOGp-ba04TtI6jVrjhOQXH43eCJ9vNuBUzdD-t8CAdmnbvH0nWpIB8kWbw5v8Sa0aQuxMjJYbLC_2Iw3X13dqnyVjp4fA7eSB8N7c1it0KEB-VKfUqiGD3VecyEZGGZbaGE8rvVet5QrY1lJ3V4yM8j6-xDc5Yndc4swOun0L3D6TYk-8gdVXUJDRjbv1ZuhZltsw".

SecurityTokenSignatureKeyNotFoundException: IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier ( IsReadOnly = False, Count = 1, Clause[0] = X509ThumbprintKeyIdentifierClause(Hash = 0xF8A59280B3D13777CC7541B3218480984F421450) ) ', token: '{"typ":"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.xkP0RwlX3CYfU0KhFsVvLJC94WK22DTqNTm71cfjiJ8VUHv3b2YhDqfq70N8mQEyiR8vTR6OQqnO6UqXqX4RXUs6ZkfK9Liv3n9NhCs97wJhP2jfefJYeScYtRmWcNNWSSL7vkm2JXQfwKOQTnOGp-ba04TtI6jVrjhOQXH43eCJ9vNuBUzdD-t8CAdmnbvH0nWpIB8kWbw5v8Sa0aQuxMjJYbLC_2Iw3X13dqnyVjp4fA7eSB8N7c1it0KEB-VKfUqiGD3VecyEZGGZbaGE8rvVet5QrY1lJ3V4yM8j6-xDc5Yndc4swOun0L3D6TYk-8gdVXUJDRjbv1ZuhZltsw'.

该组件仍处于预发布状态,因此这可能是实现中的一个缺陷,但是我想假设这是我的错误,直到排除所有可能性为止.

The component is still pre-release, so this may be a flaw in the implementation, however I want to assume it's my error until all possibilities have been ruled out.

我正在做的事情显然是错误的,还是我应该做些什么来确切了解为什么签名无法通过验证的原因?

Is there anything I'm doing which is obviously wrong, or is there something I should do to understand exactly why the signature is failing to be validated?

推荐答案

问题位于以下异常消息中:

The problem is nestled in the exception message here:

Clause [0] = X509ThumbprintKeyIdentifierClause(哈希= 0xF8A59280B3D13777CC7541B3218480984F421450)

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

使用X.509证书的默认密钥标识符子句对令牌进行签名:其指纹.元数据仅公开RSA参数和名称标识符.客户端检索元数据时,它将使用此信息而不是X.509指纹来设置RSA密钥.

The token is signed with the default key identifier clause for an X.509 certificate: its thumbprint. The metadata is exposing just the RSA parameters and a name identifier. When the client retrieves the metadata, it sets up an RSA key using this information, not an X.509 thumbprint.

要更正此错误,必须更改签名凭据以包括正确的名称标识符:

To correct this error, the signing credentials have to be changed to include the correct name identifier:

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

这包括签名中的预期标识符,并且签名已成功验证.

This includes the expected identifier in the signature, and the signature is validated successfully.

这篇关于验证JWT签名时出现SecurityTokenSignatureKeyNotFoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆