From 9c2f05abb073b7d55dd81710f04a695f124a8c91 Mon Sep 17 00:00:00 2001 From: Alexander Ignatovich Date: Sat, 27 Jan 2024 12:10:38 +0200 Subject: [PATCH] add Json Web keys collection with an ability to search keys by ids --- src/JWT/Jwk/IJwtWebKeysCollection.cs | 7 ++++ src/JWT/Jwk/JwtWebKeysCollection.cs | 38 +++++++++++++++++++ .../Jwk/JwtWebKeysCollectionTests.cs | 22 +++++++++++ tests/JWT.Tests.Common/Models/TestData.cs | 2 + 4 files changed, 69 insertions(+) create mode 100644 src/JWT/Jwk/IJwtWebKeysCollection.cs create mode 100644 src/JWT/Jwk/JwtWebKeysCollection.cs create mode 100644 tests/JWT.Tests.Common/Jwk/JwtWebKeysCollectionTests.cs diff --git a/src/JWT/Jwk/IJwtWebKeysCollection.cs b/src/JWT/Jwk/IJwtWebKeysCollection.cs new file mode 100644 index 000000000..6c96b10f2 --- /dev/null +++ b/src/JWT/Jwk/IJwtWebKeysCollection.cs @@ -0,0 +1,7 @@ +namespace JWT.Jwk +{ + public interface IJwtWebKeysCollection + { + JwtWebKey Find(string keyId); + } +} \ No newline at end of file diff --git a/src/JWT/Jwk/JwtWebKeysCollection.cs b/src/JWT/Jwk/JwtWebKeysCollection.cs new file mode 100644 index 000000000..591dd1fcc --- /dev/null +++ b/src/JWT/Jwk/JwtWebKeysCollection.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; +using JWT.Serializers; + +namespace JWT.Jwk +{ + public class JwtWebKeysCollection : IJwtWebKeysCollection + { + private readonly Dictionary _keys; + + public JwtWebKeysCollection(IEnumerable keys) + { + _keys = keys.ToDictionary(x => x.KeyId); + } + + public JwtWebKeysCollection(JwtWebKeySet keySet) : this(keySet.Keys) + { + + } + + public JwtWebKeysCollection(string keySet, IJsonSerializer serializer) + : this(serializer.Deserialize(keySet)) + { + + } + + public JwtWebKeysCollection(string keySet, IJsonSerializerFactory jsonSerializerFactory) + : this(keySet, jsonSerializerFactory.Create()) + { + + } + + public JwtWebKey Find(string keyId) + { + return _keys.TryGetValue(keyId, out var key) ? key : null; + } + } +} \ No newline at end of file diff --git a/tests/JWT.Tests.Common/Jwk/JwtWebKeysCollectionTests.cs b/tests/JWT.Tests.Common/Jwk/JwtWebKeysCollectionTests.cs new file mode 100644 index 000000000..e5723005c --- /dev/null +++ b/tests/JWT.Tests.Common/Jwk/JwtWebKeysCollectionTests.cs @@ -0,0 +1,22 @@ +using JWT.Jwk; +using JWT.Serializers; +using JWT.Tests.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace JWT.Tests.Jwk; + +[TestClass] +public class JwtWebKeysCollectionTests +{ + [TestMethod] + public void Should_Find_Json_Web_Key_By_KeyId() + { + var serializerFactory = new DefaultJsonSerializerFactory(); + + var collection = new JwtWebKeysCollection(TestData.JsonWebKeySet, serializerFactory); + + var jwk = collection.Find(TestData.ServerRsaPublicThumbprint1); + + Assert.IsNotNull(jwk); + } +} \ No newline at end of file diff --git a/tests/JWT.Tests.Common/Models/TestData.cs b/tests/JWT.Tests.Common/Models/TestData.cs index 3db70255c..5fe6cf8fb 100644 --- a/tests/JWT.Tests.Common/Models/TestData.cs +++ b/tests/JWT.Tests.Common/Models/TestData.cs @@ -67,6 +67,8 @@ public class TestDataSystemTextSerializerDecorated public const string TokenByAsymmetricAlgorithm = "eyJraWQiOiJDRkFFQUUyRDY1MEE2Q0E5ODYyNTc1REU1NDM3MUVBOTgwNjQzODQ5IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJ0ZXN0IiwiZXhwIjoyMTQ3NDgzNjQ4LCJGaXJzdE5hbWUiOiJKZXN1cyIsIkFnZSI6MzN9.ZeGfWN3kBHZLiSh4jzzn6kx7F6lNu5OsowZW0Sv-_wpSgQO2_QXFUPLx23wm4J9rjMGQlSksEtCLd_X3iiBOBLbxAUWzdj59iJIAh485unZj12sBJ7KHDVsOMc6DcSJdwRo9S9yiJ_RJ57R-dn4uRdZTBXBZHrrmb35UjaAG6hFfu5d1Ap4ZjLxqDJGl0Wo4j5l6vR8HFpmiFHvqPQ4apjqkBGnitJ7oghbeRX0SIVNSkXbBDp3i9pC-hxzs2oHZC9ys0rJlfpxLls3MV4oQbQ7m6W9MrwwsdObJHI7PiTNfObLKdgySi6WkQS7rwXVz0DqRa8TXv8_USkvhsyGLMQ"; + public const string JsonWebKeySet = "{\"keys\":[{\"kty\":\"RSA\",\"kid\":\"CFAEAE2D650A6CA9862575DE54371EA980643849\",\"use\":\"sig\",\"n\":\"uYTPtHCIztKC3MUDxnZ0ktGVSQ0jVbD5rYl4pki4RCD3M22d-TklmvTyPj0SM7a_8o7cI05QhEuBI8hKCfC2CEJhlS3WFeVC0vwsl1aYFqQ3Ykr-kDsAdqjL95ioj3JmiscvqKOM34oQahpAgukJ7Kcr1BT2Ylk8fOgKcN7t1qgURNx0Pj4zJ4w0p1nT2gLG--bYutUVPvamI9wcMQyUesZwGmM9UUpMRzsOPk8vv7TbTm62Zkx-5rFUaVe5DFNUIMg92NvyU0392FFNCwptSflidHDG1ayCwL1ZTkJ0Z9yJXCNSzi_3ulxMhE-bVcpr_EuRKCYxn9qPFZ07Bd77bQ\",\"e\":\"AQAB\"}]}"; + public static readonly IDictionary DictionaryPayload = new Dictionary { { nameof(Customer.FirstName), Customer.FirstName },