diff --git a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs index 293049b936..c250858c87 100644 --- a/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs +++ b/src/Microsoft.IdentityModel.Protocols.OpenIdConnect/Json/OpenIdConnectConfigurationSerializer.cs @@ -158,6 +158,14 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (reader.ValueTextEquals(Utf8Bytes.EndSessionEndpoint)) config.EndSessionEndpoint = JsonPrimitives.ReadString(ref reader, MetadataName.EndSessionEndpoint, ClassName, true); + else if (reader.ValueTextEquals(Encoding.UTF8.GetBytes(JsonWebKeySetParameterNames.Keys))) + { + reader.Read(); + if (config.JsonWebKeySet == null) + config.JsonWebKeySet = new JsonWebKeySet(); + JsonWebKeySetSerializer.Read(ref reader, config.JsonWebKeySet); + } + // FrontchannelLogoutSessionSupported and FrontchannelLogoutSupported are per spec 'boolean'. // We shipped pervious versions accepting a string and transforming to a boolean. else if (reader.ValueTextEquals(Utf8Bytes.FrontchannelLogoutSessionSupported)) @@ -282,9 +290,6 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (reader.ValueTextEquals(Utf8Bytes.UserInfoSigningAlgValuesSupported)) JsonPrimitives.ReadStrings(ref reader, config.UserInfoEndpointSigningAlgValuesSupported, MetadataName.UserInfoSigningAlgValuesSupported, ClassName, true); - else if (reader.ValueTextEquals(JsonWebKeySetParameterNames.Keys)) - JsonWebKeySetSerializer.ReadKeys(ref reader, config.JsonWebKeySet); - #endregion else { @@ -359,91 +364,91 @@ public static OpenIdConnectConfiguration Read(ref Utf8JsonReader reader, OpenIdC else if (propertyName.Equals(MetadataName.IdTokenEncryptionEncValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.IdTokenEncryptionEncValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName.IdTokenSigningAlgValuesSupported , StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.IdTokenSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.IdTokenSigningAlgValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. IntrospectionEndpoint, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.IntrospectionEndpoint, StringComparison.OrdinalIgnoreCase)) config.IntrospectionEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. IntrospectionEndpointAuthMethodsSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.IntrospectionEndpointAuthMethodsSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.IntrospectionEndpointAuthMethodsSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. IntrospectionEndpointAuthSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.IntrospectionEndpointAuthSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.IntrospectionEndpointAuthSigningAlgValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. Issuer, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.Issuer, StringComparison.OrdinalIgnoreCase)) config.Issuer = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. JwksUri, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.JwksUri, StringComparison.OrdinalIgnoreCase)) config.JwksUri = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. LogoutSessionSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.LogoutSessionSupported, StringComparison.OrdinalIgnoreCase)) config.LogoutSessionSupported = JsonPrimitives.ReadBoolean(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. OpPolicyUri, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.OpPolicyUri, StringComparison.OrdinalIgnoreCase)) config.OpPolicyUri = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. OpTosUri, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.OpTosUri, StringComparison.OrdinalIgnoreCase)) config.OpTosUri = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. RegistrationEndpoint, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.RegistrationEndpoint, StringComparison.OrdinalIgnoreCase)) config.RegistrationEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. RequestObjectEncryptionAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.RequestObjectEncryptionAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.RequestObjectEncryptionAlgValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. RequestObjectEncryptionEncValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.RequestObjectEncryptionEncValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.RequestObjectEncryptionEncValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. RequestObjectSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.RequestObjectSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.RequestObjectSigningAlgValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. RequestParameterSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.RequestParameterSupported, StringComparison.OrdinalIgnoreCase)) config.RequestParameterSupported = JsonPrimitives.ReadBoolean(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. RequestUriParameterSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.RequestUriParameterSupported, StringComparison.OrdinalIgnoreCase)) config.RequestUriParameterSupported = JsonPrimitives.ReadBoolean(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. RequireRequestUriRegistration, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.RequireRequestUriRegistration, StringComparison.OrdinalIgnoreCase)) config.RequireRequestUriRegistration = JsonPrimitives.ReadBoolean(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. ResponseModesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.ResponseModesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.ResponseModesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. ResponseTypesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.ResponseTypesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.ResponseTypesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. ScopesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.ScopesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.ScopesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. ServiceDocumentation, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.ServiceDocumentation, StringComparison.OrdinalIgnoreCase)) config.ServiceDocumentation = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. SubjectTypesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.SubjectTypesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.SubjectTypesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. TokenEndpoint, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.TokenEndpoint, StringComparison.OrdinalIgnoreCase)) config.TokenEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. TokenEndpointAuthMethodsSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.TokenEndpointAuthMethodsSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.TokenEndpointAuthMethodsSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. TokenEndpointAuthSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.TokenEndpointAuthSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.TokenEndpointAuthSigningAlgValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. UILocalesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.UILocalesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.UILocalesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. UserInfoEncryptionAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.UserInfoEncryptionAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.UserInfoEndpointEncryptionAlgValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. UserInfoEncryptionEncValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.UserInfoEncryptionEncValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.UserInfoEndpointEncryptionEncValuesSupported, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. UserInfoEndpoint, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.UserInfoEndpoint, StringComparison.OrdinalIgnoreCase)) config.UserInfoEndpoint = JsonPrimitives.ReadString(ref reader, propertyName, ClassName); - else if (propertyName.Equals(MetadataName. UserInfoSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) + else if (propertyName.Equals(MetadataName.UserInfoSigningAlgValuesSupported, StringComparison.OrdinalIgnoreCase)) JsonPrimitives.ReadStrings(ref reader, config.UserInfoEndpointSigningAlgValuesSupported, propertyName, ClassName); } @@ -585,7 +590,10 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.ResponseTypesSupported, config.ResponseTypesSupported); if (config.ShouldSerializeJsonWebKeys && config.JsonWebKeySet != null && config.JsonWebKeySet.Keys.Count > 0) + { + writer.WritePropertyName(Encoding.UTF8.GetBytes(JsonWebKeySetParameterNames.Keys)); JsonWebKeySetSerializer.Write(ref writer, config.JsonWebKeySet); + } if (config.ScopesSupported.Count > 0) JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.ScopesSupported, config.ScopesSupported); @@ -619,7 +627,7 @@ public static void Write(ref Utf8JsonWriter writer, OpenIdConnectConfiguration c if (config.UserInfoEndpointSigningAlgValuesSupported.Count > 0) JsonPrimitives.WriteStrings(ref writer, Utf8Bytes.UserInfoSigningAlgValuesSupported, config.UserInfoEndpointSigningAlgValuesSupported); - + if (config.AdditionalData.Count > 0) JsonPrimitives.WriteObjects(ref writer, config.AdditionalData); diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs index 242adfb623..f887eccadd 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConfigData.cs @@ -594,17 +594,6 @@ public static OpenIdConnectConfiguration Default get => SetDefaultConfiguration(new OpenIdConnectConfiguration()); } - public static OpenIdConnectConfiguration WithJsonWebKeySet - { - get - { - var config = Default; - config.JsonWebKeySet = JsonUtilities.FullyPopulatedJsonWebKeySet(); - config.ShouldSerializeJsonWebKeys = true; - return config; - } - } - private static OpenIdConnectConfiguration SetDefaultConfiguration(OpenIdConnectConfiguration config) { AddToCollection(config.AcrValuesSupported, "acr_value1", "acr_value2", "acr_value3"); diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs index e916d6c613..9917fb517f 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectConfigurationTests.cs @@ -126,6 +126,22 @@ public void DeserializeOpenIdConnectConfigurationWithSigningKeys() TestUtilities.AssertFailIfErrors(context); } + [Fact] + public void DeserializeOpenIdConnectConfigurationWithJsonWebKeySet() + { + TestUtilities.WriteHeader($"{this}.DeserializeOpenIdConnectConfigurationWithJsonWebKeySet"); + var context = new CompareContext(); + var config = OpenIdConfigData.FullyPopulatedWithKeys; + config.ShouldSerializeJsonWebKeys = true; + var json = OpenIdConnectConfiguration.Write(config); + var actualConfig = OpenIdConnectConfiguration.Create(json); + + // "JsonWebKeySet" should be identical + IdentityComparer.AreEqual(OpenIdConfigData.FullyPopulatedWithKeys.JsonWebKeySet, actualConfig.JsonWebKeySet, context); + + TestUtilities.AssertFailIfErrors(context); + } + [Fact] public void GetSets() { diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs index 3787368589..d67305e561 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectSerializationTests.cs @@ -40,7 +40,7 @@ public static TheoryData DesrializeTheoryData get { TheoryData theoryData = new TheoryData(); - + // the reason to replace AdditionalData with upper case is because the test deserializes uppercase and lowercase. // we wanted to leave the data sets in original form from discovery to be used in other tests. theoryData.Add(new OpenIdConnectTheoryData("AADCommonV1") @@ -138,15 +138,16 @@ public static TheoryData DesrializeTheoryData CompareTo = OpenIdConfigData.NullConfig, Json = JsonData.NullObject }); - + theoryData.Add(new OpenIdConnectTheoryData("SerializeJsonWebKeySet") { - CompareTo = OpenIdConfigData.WithJsonWebKeySet, - Json = "" + CompareTo = OpenIdConfigData.FullyPopulatedWithKeys, + Json = OpenIdConfigData.JsonAllValues }); return theoryData; } } + } }