Browse Source

Replace JsonSerializer.Serialize() by Utf8JsonWriter and JsonSerializer.Deserialize() by JsonDocument

pull/1090/head
Kévin Chalet 5 years ago
parent
commit
0b629b3dbd
  1. 58
      src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs
  2. 56
      src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs
  3. 147
      src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs
  4. 57
      src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
  5. 77
      src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs
  6. 30
      src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs
  7. 147
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
  8. 57
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
  9. 77
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
  10. 30
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs
  11. 41
      src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs
  12. 35
      src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs
  13. 35
      src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbScopeStore.cs
  14. 33
      src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs
  15. 9
      src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs
  16. 36
      src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs
  17. 9
      src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs
  18. 65
      src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs
  19. 9
      src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs
  20. 18
      src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs
  21. 9
      src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs
  22. 1
      test/OpenIddict.Server.IntegrationTests/OpenIddict.Server.IntegrationTests.csproj
  23. 9
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs

58
src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs

@ -9,8 +9,10 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using Microsoft.Extensions.Primitives;
@ -517,9 +519,21 @@ namespace OpenIddict.Abstractions
return ImmutableArray.Create<string>();
}
return JsonSerializer.Deserialize<IEnumerable<string>>(destinations)
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToImmutableArray();
using var document = JsonDocument.Parse(destinations);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
var value = element.GetString();
if (builder.Contains(value, StringComparer.OrdinalIgnoreCase))
{
continue;
}
builder.Add(value);
}
return builder.ToImmutable();
}
/// <summary>
@ -546,8 +560,18 @@ namespace OpenIddict.Abstractions
return false;
}
return JsonSerializer.Deserialize<IEnumerable<string>>(destinations)
.Contains(destination, StringComparer.OrdinalIgnoreCase);
using var document = JsonDocument.Parse(destinations);
foreach (var element in document.RootElement.EnumerateArray())
{
var value = element.GetString();
if (string.Equals(value, destination, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
/// <summary>
@ -574,12 +598,24 @@ namespace OpenIddict.Abstractions
throw new ArgumentException(SR.GetResourceString(SR.ID1181), nameof(destinations));
}
claim.Properties[Properties.Destinations] =
JsonSerializer.Serialize(destinations.Distinct(StringComparer.OrdinalIgnoreCase), new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
});
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Indented = false
});
writer.WriteStartArray();
foreach (var destination in destinations.Distinct(StringComparer.OrdinalIgnoreCase))
{
writer.WriteStringValue(destination);
}
writer.WriteEndArray();
writer.Flush();
claim.Properties[Properties.Destinations] = Encoding.UTF8.GetString(stream.ToArray());
return claim;
}

56
src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs

@ -9,7 +9,9 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using SR = OpenIddict.Abstractions.OpenIddictResources;
@ -624,18 +626,10 @@ namespace OpenIddict.Abstractions
// to a JSON object or array), try to deserialize it to get a JsonElement instance.
string value when value.Length != 0 && (value[0] == '{' || value[0] == '[') =>
DeserializeElement(value) ??
DeserializeElement(JsonSerializer.Serialize(value, new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
})) ?? default,
DeserializeElement(SerializeObject(value)) ?? default,
// Otherwise, serialize it to get a JsonElement instance.
var value => DeserializeElement(JsonSerializer.Serialize(value, new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
})) ?? default
var value => DeserializeElement(SerializeObject(value)) ?? default
};
static JsonElement? DeserializeElement(string value)
@ -651,6 +645,48 @@ namespace OpenIddict.Abstractions
return null;
}
}
static string SerializeObject(object instance)
{
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Indented = false
});
switch (instance)
{
case bool value:
writer.WriteBooleanValue(value);
break;
case long value:
writer.WriteNumberValue(value);
break;
case string value:
writer.WriteStringValue(value);
break;
case string?[] value:
writer.WriteStartArray();
for (var index = 0; index < value.Length; index++)
{
writer.WriteStringValue(value[index]);
}
writer.WriteEndArray();
break;
default: throw new InvalidOperationException(SR.GetResourceString(SR.ID1193));
}
writer.Flush();
return Encoding.UTF8.GetString(stream.ToArray());
}
}
/// <summary>

147
src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs

@ -399,8 +399,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<Dictionary<string, string>>(application.DisplayNames)
.ToImmutableDictionary(name => CultureInfo.GetCultureInfo(name.Key), name => name.Value);
using var document = JsonDocument.Parse(application.DisplayNames);
var builder = ImmutableDictionary.CreateBuilder<CultureInfo, string>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<CultureInfo, string>>(names);
@ -438,7 +445,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.Permissions);
using var document = JsonDocument.Parse(application.Permissions);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(permissions);
@ -465,7 +480,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.PostLogoutRedirectUris);
using var document = JsonDocument.Parse(application.PostLogoutRedirectUris);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(addresses);
@ -492,7 +515,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(application.Properties);
using var document = JsonDocument.Parse(application.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -519,7 +550,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.RedirectUris);
using var document = JsonDocument.Parse(application.RedirectUris);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(addresses);
@ -546,7 +585,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.Requirements);
using var document = JsonDocument.Parse(application.Requirements);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(requirements);
@ -718,12 +765,25 @@ namespace OpenIddict.EntityFramework
return default;
}
application.Permissions = JsonSerializer.Serialize(permissions, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var permission in permissions)
{
writer.WriteStringValue(permission);
}
writer.WriteEndArray();
writer.Flush();
application.Permissions = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -743,12 +803,25 @@ namespace OpenIddict.EntityFramework
return default;
}
application.PostLogoutRedirectUris = JsonSerializer.Serialize(addresses, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var address in addresses)
{
writer.WriteStringValue(address);
}
writer.WriteEndArray();
writer.Flush();
application.PostLogoutRedirectUris = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -768,12 +841,26 @@ namespace OpenIddict.EntityFramework
return default;
}
application.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
application.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -793,12 +880,25 @@ namespace OpenIddict.EntityFramework
return default;
}
application.RedirectUris = JsonSerializer.Serialize(addresses, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var address in addresses)
{
writer.WriteStringValue(address);
}
writer.WriteEndArray();
writer.Flush();
application.RedirectUris = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -817,12 +917,25 @@ namespace OpenIddict.EntityFramework
return default;
}
application.Requirements = JsonSerializer.Serialize(requirements, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var requirement in requirements)
{
writer.WriteStringValue(requirement);
}
writer.WriteEndArray();
writer.Flush();
application.Requirements = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

57
src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs

@ -11,8 +11,10 @@ using System.ComponentModel;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -452,7 +454,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(authorization.Properties);
using var document = JsonDocument.Parse(authorization.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -479,7 +489,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(authorization.Scopes);
using var document = JsonDocument.Parse(authorization.Scopes);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(scopes);
@ -707,12 +725,26 @@ namespace OpenIddict.EntityFramework
return default;
}
authorization.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
authorization.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -732,12 +764,25 @@ namespace OpenIddict.EntityFramework
return default;
}
authorization.Scopes = JsonSerializer.Serialize(scopes, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var scope in scopes)
{
writer.WriteStringValue(scope);
}
writer.WriteEndArray();
writer.Flush();
authorization.Scopes = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

77
src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs

@ -260,8 +260,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<Dictionary<string, string>>(scope.Descriptions)
.ToImmutableDictionary(description => CultureInfo.GetCultureInfo(description.Key), description => description.Value);
using var document = JsonDocument.Parse(scope.Descriptions);
var builder = ImmutableDictionary.CreateBuilder<CultureInfo, string>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<CultureInfo, string>>(descriptions);
@ -299,8 +306,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<Dictionary<string, string>>(scope.DisplayNames)
.ToImmutableDictionary(name => CultureInfo.GetCultureInfo(name.Key), name => name.Value);
using var document = JsonDocument.Parse(scope.DisplayNames);
var builder = ImmutableDictionary.CreateBuilder<CultureInfo, string>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<CultureInfo, string>>(names);
@ -349,7 +363,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(scope.Properties);
using var document = JsonDocument.Parse(scope.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -376,7 +398,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(scope.Resources);
using var document = JsonDocument.Parse(scope.Resources);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(resources);
@ -561,12 +591,26 @@ namespace OpenIddict.EntityFramework
return default;
}
scope.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
scope.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -585,12 +629,25 @@ namespace OpenIddict.EntityFramework
return default;
}
scope.Resources = JsonSerializer.Serialize(resources, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var resource in resources)
{
writer.WriteStringValue(resource);
}
writer.WriteEndArray();
writer.Flush();
scope.Resources = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

30
src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs

@ -11,7 +11,9 @@ using System.ComponentModel;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -444,7 +446,15 @@ namespace OpenIddict.EntityFramework
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(token.Properties);
using var document = JsonDocument.Parse(token.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -746,12 +756,26 @@ namespace OpenIddict.EntityFramework
return default;
}
token.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
token.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

147
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs

@ -450,8 +450,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<Dictionary<string, string>>(application.DisplayNames)
.ToImmutableDictionary(name => CultureInfo.GetCultureInfo(name.Key), name => name.Value);
using var document = JsonDocument.Parse(application.DisplayNames);
var builder = ImmutableDictionary.CreateBuilder<CultureInfo, string>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<CultureInfo, string>>(names);
@ -489,7 +496,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.Permissions);
using var document = JsonDocument.Parse(application.Permissions);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(permissions);
@ -516,7 +531,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.PostLogoutRedirectUris);
using var document = JsonDocument.Parse(application.PostLogoutRedirectUris);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(addresses);
@ -543,7 +566,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(application.Properties);
using var document = JsonDocument.Parse(application.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -570,7 +601,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.RedirectUris);
using var document = JsonDocument.Parse(application.RedirectUris);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(addresses);
@ -597,7 +636,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(application.Requirements);
using var document = JsonDocument.Parse(application.Requirements);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(requirements);
@ -768,12 +815,25 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
application.Permissions = JsonSerializer.Serialize(permissions, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var permission in permissions)
{
writer.WriteStringValue(permission);
}
writer.WriteEndArray();
writer.Flush();
application.Permissions = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -793,12 +853,25 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
application.PostLogoutRedirectUris = JsonSerializer.Serialize(addresses, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var address in addresses)
{
writer.WriteStringValue(address);
}
writer.WriteEndArray();
writer.Flush();
application.PostLogoutRedirectUris = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -818,12 +891,26 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
application.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
application.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -843,12 +930,25 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
application.RedirectUris = JsonSerializer.Serialize(addresses, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var address in addresses)
{
writer.WriteStringValue(address);
}
writer.WriteEndArray();
writer.Flush();
application.RedirectUris = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -867,12 +967,25 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
application.Requirements = JsonSerializer.Serialize(requirements, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var requirement in requirements)
{
writer.WriteStringValue(requirement);
}
writer.WriteEndArray();
writer.Flush();
application.Requirements = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

57
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs

@ -9,8 +9,10 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -520,7 +522,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(authorization.Properties);
using var document = JsonDocument.Parse(authorization.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -547,7 +557,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(authorization.Scopes);
using var document = JsonDocument.Parse(authorization.Scopes);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(scopes);
@ -793,12 +811,26 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
authorization.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
authorization.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -818,12 +850,25 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
authorization.Scopes = JsonSerializer.Serialize(scopes, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var scope in scopes)
{
writer.WriteStringValue(scope);
}
writer.WriteEndArray();
writer.Flush();
authorization.Scopes = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

77
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs

@ -276,8 +276,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<Dictionary<string, string>>(scope.Descriptions)
.ToImmutableDictionary(description => CultureInfo.GetCultureInfo(description.Key), description => description.Value);
using var document = JsonDocument.Parse(scope.Descriptions);
var builder = ImmutableDictionary.CreateBuilder<CultureInfo, string>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<CultureInfo, string>>(descriptions);
@ -315,8 +322,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<Dictionary<string, string>>(scope.DisplayNames)
.ToImmutableDictionary(name => CultureInfo.GetCultureInfo(name.Key), name => name.Value);
using var document = JsonDocument.Parse(scope.DisplayNames);
var builder = ImmutableDictionary.CreateBuilder<CultureInfo, string>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[CultureInfo.GetCultureInfo(property.Name)] = property.Value.GetString();
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<CultureInfo, string>>(names);
@ -365,7 +379,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(scope.Properties);
using var document = JsonDocument.Parse(scope.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -392,7 +414,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableArray<string>>(scope.Resources);
using var document = JsonDocument.Parse(scope.Resources);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableArray<string>>(resources);
@ -577,12 +607,26 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
scope.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
scope.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}
@ -601,12 +645,25 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
scope.Resources = JsonSerializer.Serialize(resources, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var resource in resources)
{
writer.WriteStringValue(resource);
}
writer.WriteEndArray();
writer.Flush();
scope.Resources = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

30
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs

@ -9,7 +9,9 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -496,7 +498,15 @@ namespace OpenIddict.EntityFrameworkCore
entry.SetPriority(CacheItemPriority.High)
.SetSlidingExpiration(TimeSpan.FromMinutes(1));
return JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(token.Properties);
using var document = JsonDocument.Parse(token.Properties);
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return builder.ToImmutable();
});
return new ValueTask<ImmutableDictionary<string, JsonElement>>(properties);
@ -821,12 +831,26 @@ namespace OpenIddict.EntityFrameworkCore
return default;
}
token.Properties = JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
token.Properties = Encoding.UTF8.GetString(stream.ToArray());
return default;
}

41
src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs

@ -8,8 +8,10 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -336,8 +338,15 @@ namespace OpenIddict.MongoDb
return new ValueTask<ImmutableDictionary<string, JsonElement>>(ImmutableDictionary.Create<string, JsonElement>());
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(
JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(application.Properties.ToJson()));
using var document = JsonDocument.Parse(application.Properties.ToJson());
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(builder.ToImmutable());
}
/// <inheritdoc/>
@ -536,7 +545,7 @@ namespace OpenIddict.MongoDb
return default;
}
application.Permissions = permissions.ToArray();
application.Permissions = permissions;
return default;
}
@ -557,7 +566,7 @@ namespace OpenIddict.MongoDb
return default;
}
application.PostLogoutRedirectUris = addresses.ToArray();
application.PostLogoutRedirectUris = addresses;
return default;
}
@ -578,11 +587,25 @@ namespace OpenIddict.MongoDb
return default;
}
application.Properties = BsonDocument.Parse(JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
}));
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
application.Properties = BsonDocument.Parse(Encoding.UTF8.GetString(stream.ToArray()));
return default;
}
@ -603,7 +626,7 @@ namespace OpenIddict.MongoDb
return default;
}
application.RedirectUris = addresses.ToArray();
application.RedirectUris = addresses;
return default;
}
@ -624,7 +647,7 @@ namespace OpenIddict.MongoDb
return default;
}
application.Requirements = requirements.ToArray();
application.Requirements = requirements;
return default;
}

35
src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs

@ -7,8 +7,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -396,8 +398,15 @@ namespace OpenIddict.MongoDb
return new ValueTask<ImmutableDictionary<string, JsonElement>>(ImmutableDictionary.Create<string, JsonElement>());
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(
JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(authorization.Properties.ToJson()));
using var document = JsonDocument.Parse(authorization.Properties.ToJson());
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(builder.ToImmutable());
}
/// <inheritdoc/>
@ -615,11 +624,25 @@ namespace OpenIddict.MongoDb
return default;
}
authorization.Properties = BsonDocument.Parse(JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
}));
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
authorization.Properties = BsonDocument.Parse(Encoding.UTF8.GetString(stream.ToArray()));
return default;
}
@ -640,7 +663,7 @@ namespace OpenIddict.MongoDb
return default;
}
authorization.Scopes = scopes.ToArray();
authorization.Scopes = scopes;
return default;
}

35
src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbScopeStore.cs

@ -8,8 +8,10 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -285,8 +287,15 @@ namespace OpenIddict.MongoDb
return new ValueTask<ImmutableDictionary<string, JsonElement>>(ImmutableDictionary.Create<string, JsonElement>());
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(
JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(scope.Properties.ToJson()));
using var document = JsonDocument.Parse(scope.Properties.ToJson());
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(builder.ToImmutable());
}
/// <inheritdoc/>
@ -452,11 +461,25 @@ namespace OpenIddict.MongoDb
return default;
}
scope.Properties = BsonDocument.Parse(JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
}));
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
scope.Properties = BsonDocument.Parse(Encoding.UTF8.GetString(stream.ToArray()));
return default;
}
@ -476,7 +499,7 @@ namespace OpenIddict.MongoDb
return default;
}
scope.Resources = resources.ToArray();
scope.Resources = resources;
return default;
}

33
src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs

@ -7,8 +7,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
@ -417,8 +419,15 @@ namespace OpenIddict.MongoDb
return new ValueTask<ImmutableDictionary<string, JsonElement>>(ImmutableDictionary.Create<string, JsonElement>());
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(
JsonSerializer.Deserialize<ImmutableDictionary<string, JsonElement>>(token.Properties.ToJson()));
using var document = JsonDocument.Parse(token.Properties.ToJson());
var builder = ImmutableDictionary.CreateBuilder<string, JsonElement>();
foreach (var property in document.RootElement.EnumerateObject())
{
builder[property.Name] = property.Value;
}
return new ValueTask<ImmutableDictionary<string, JsonElement>>(builder.ToImmutable());
}
/// <inheritdoc/>
@ -677,11 +686,25 @@ namespace OpenIddict.MongoDb
return default;
}
token.Properties = BsonDocument.Parse(JsonSerializer.Serialize(properties, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
}));
Indented = false
});
writer.WriteStartObject();
foreach (var property in properties)
{
writer.WritePropertyName(property.Key);
property.Value.WriteTo(writer);
}
writer.WriteEndObject();
writer.Flush();
token.Properties = BsonDocument.Parse(Encoding.UTF8.GetString(stream.ToArray()));
return default;
}

9
src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs

@ -1062,6 +1062,8 @@ namespace OpenIddict.Server.AspNetCore
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response is not null, SR.GetResourceString(SR.ID5007));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpRequest()?.HttpContext.Response;
@ -1073,12 +1075,15 @@ namespace OpenIddict.Server.AspNetCore
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = true
});
context.Transaction.Response.WriteTo(writer);
writer.Flush();
response.ContentLength = stream.Length;
response.ContentType = "application/json;charset=UTF-8";

36
src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs

@ -10,6 +10,7 @@ using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using OpenIddict.Abstractions;
@ -180,8 +181,22 @@ namespace OpenIddict.Server.DataProtection
=> properties.TryGetValue(name, out var value) ? value : null;
static ImmutableArray<string> GetArrayProperty(IReadOnlyDictionary<string, string> properties, string name)
=> properties.TryGetValue(name, out var value) ?
JsonSerializer.Deserialize<ImmutableArray<string>>(value) : ImmutableArray.Create<string>();
{
if (properties.TryGetValue(name, out var value))
{
using var document = JsonDocument.Parse(value);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
}
return ImmutableArray.Create<string>();
}
}
public void WriteToken(BinaryWriter writer, ClaimsPrincipal principal)
@ -381,11 +396,24 @@ namespace OpenIddict.Server.DataProtection
else
{
properties[name] = JsonSerializer.Serialize(values, new JsonSerializerOptions
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = false
});
writer.WriteStartArray();
foreach (var value in values)
{
writer.WriteStringValue(value);
}
writer.WriteEndArray();
writer.Flush();
properties[name] = Encoding.UTF8.GetString(stream.ToArray());
}
}
}

9
src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs

@ -999,6 +999,8 @@ namespace OpenIddict.Server.Owin
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response is not null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -1010,12 +1012,15 @@ namespace OpenIddict.Server.Owin
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = true
});
context.Transaction.Response.WriteTo(writer);
writer.Flush();
response.ContentLength = stream.Length;
response.ContentType = "application/json;charset=UTF-8";

65
src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs

@ -5,11 +5,15 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
@ -998,8 +1002,8 @@ namespace OpenIddict.Server
continue;
}
var claims = grouping.ToArray();
context.Claims[type] = claims.Length switch
var claims = grouping.ToList();
context.Claims[type] = claims.Count switch
{
// When there's only one claim with the same type, directly
// convert the claim using the specified claim value type.
@ -1007,12 +1011,7 @@ namespace OpenIddict.Server
// When multiple claims share the same type, retrieve the underlying
// JSON values and add everything to a new unique JSON array.
_ => DeserializeElement(JsonSerializer.Serialize(
claims.Select(claim => ConvertToParameter(claim).Value), new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
}))
_ => DeserializeElement(SerializeClaims(claims))
};
}
@ -1035,6 +1034,56 @@ namespace OpenIddict.Server
using var document = JsonDocument.Parse(value);
return document.RootElement.Clone();
}
static string SerializeClaims(IReadOnlyList<Claim> claims)
{
using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
Indented = false
});
writer.WriteStartArray();
for (var index = 0; index < claims.Count; index++)
{
var claim = claims[index];
switch (claim.ValueType)
{
case ClaimValueTypes.Boolean:
writer.WriteBooleanValue(bool.Parse(claim.Value));
break;
case ClaimValueTypes.Integer:
case ClaimValueTypes.Integer32:
writer.WriteNumberValue(int.Parse(claim.Value, CultureInfo.InvariantCulture));
break;
case ClaimValueTypes.Integer64:
writer.WriteNumberValue(long.Parse(claim.Value, CultureInfo.InvariantCulture));
break;
case JsonClaimValueTypes.Json:
case JsonClaimValueTypes.JsonArray:
using (var document = JsonDocument.Parse(claim.Value))
{
document.WriteTo(writer);
}
break;
default:
writer.WriteStringValue(claim.Value);
break;
}
}
writer.WriteEndArray();
writer.Flush();
return Encoding.UTF8.GetString(stream.ToArray());
}
}
}

9
src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs

@ -608,6 +608,8 @@ namespace OpenIddict.Validation.AspNetCore
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response is not null, SR.GetResourceString(SR.ID5007));
// This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetHttpRequest()?.HttpContext.Response;
@ -619,12 +621,15 @@ namespace OpenIddict.Validation.AspNetCore
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = true
});
context.Transaction.Response.WriteTo(writer);
writer.Flush();
response.ContentLength = stream.Length;
response.ContentType = "application/json;charset=UTF-8";

18
src/OpenIddict.Validation.DataProtection/OpenIddictValidationDataProtectionFormatter.cs

@ -178,8 +178,22 @@ namespace OpenIddict.Validation.DataProtection
=> properties.TryGetValue(name, out var value) ? value : null;
static ImmutableArray<string> GetArrayProperty(IReadOnlyDictionary<string, string> properties, string name)
=> properties.TryGetValue(name, out var value) ?
JsonSerializer.Deserialize<ImmutableArray<string>>(value) : ImmutableArray.Create<string>();
{
if (properties.TryGetValue(name, out var value))
{
using var document = JsonDocument.Parse(value);
var builder = ImmutableArray.CreateBuilder<string>(document.RootElement.GetArrayLength());
foreach (var element in document.RootElement.EnumerateArray())
{
builder.Add(element.GetString());
}
return builder.ToImmutable();
}
return ImmutableArray.Create<string>();
}
}
}
}

9
src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs

@ -615,6 +615,8 @@ namespace OpenIddict.Validation.Owin
throw new ArgumentNullException(nameof(context));
}
Debug.Assert(context.Transaction.Response is not null, SR.GetResourceString(SR.ID5007));
// This handler only applies to OWIN requests. If The OWIN request cannot be resolved,
// this may indicate that the request was incorrectly processed by another server stack.
var response = context.Transaction.GetOwinRequest()?.Context.Response;
@ -626,12 +628,15 @@ namespace OpenIddict.Validation.Owin
context.Logger.LogInformation(SR.GetResourceString(SR.ID7142), context.Transaction.Response);
using var stream = new MemoryStream();
await JsonSerializer.SerializeAsync(stream, context.Transaction.Response, new JsonSerializerOptions
using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = false
Indented = true
});
context.Transaction.Response.WriteTo(writer);
writer.Flush();
response.ContentLength = stream.Length;
response.ContentType = "application/json;charset=UTF-8";

1
test/OpenIddict.Server.IntegrationTests/OpenIddict.Server.IntegrationTests.csproj

@ -20,6 +20,7 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Moq" />
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="System.Net.Http.Json" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">

9
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs

@ -9,9 +9,9 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
using AngleSharp.Html.Parser;
using Microsoft.Extensions.Primitives;
@ -421,12 +421,7 @@ namespace OpenIddict.Server.IntegrationTests
else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "application/json", StringComparison.OrdinalIgnoreCase))
{
// Note: this test client is only used with OpenIddict's ASP.NET Core or OWIN hosts,
// that always return their HTTP responses encoded using UTF-8. As such, the stream
// returned by ReadAsStreamAsync() is always assumed to contain UTF-8 encoded payloads.
using var stream = await message.Content.ReadAsStreamAsync();
return await JsonSerializer.DeserializeAsync<OpenIddictResponse>(stream);
return await message.Content.ReadFromJsonAsync<OpenIddictResponse>();
}
else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/html", StringComparison.OrdinalIgnoreCase))

Loading…
Cancel
Save