validationJWT签名时的SecurityTokenSignatureKeyNotFoundException

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

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

{ "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类使用JwtSecurityToken类及其关联的处理程序生成标识令牌。 此代码表示如何构造令牌并将其作为响应数据的参数返回给调用系统。

 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并尝试validation令牌的签名。 这样做会引发以下exception:

SecurityTokenSignatureKeyNotFoundException:IDX10500:签名validation失败。 无法解析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-VKfUqiGD3VecyEZGGZbaGE8rvVet5 QrY1lJ3V4yM8j6-xDc5Yndc4swOun0L3D6TYk-8gdVXUJDRjbv1ZuhZltsw”。

该组件仍然是预发布的,因此这可能是实现中的一个缺陷,但是我想假设它是我的错误,直到排除了所有可能性。

有什么我正在做的显然是错误的,或者我应该做些什么来明白为什么签名无法validation?

问题出现在这里的exception消息中:

条款[0] = X509ThumbprintKeyIdentifierClause(Hash = 0xF8A59280B3D13777CC7541B3218480984F421450)

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

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

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

这包括签名中的预期标识符,并且签名已成功validation。