Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added option to select serializer #433

Merged
merged 48 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
8b25f5f
First take
Aug 25, 2022
f94fc90
added some tests
Aug 25, 2022
81af0db
Update JwtBuilderEncodeTests.cs
abatishchev Aug 26, 2022
73fe125
Update JwtEncoderTests.cs
abatishchev Aug 26, 2022
1ee6b46
bumped version
Aug 26, 2022
c1a5b3c
Added assert to test and method to the JsonSerializerFactory
Aug 26, 2022
1c4421b
Lowered target framework for .net40 test so we get net461 so it uses …
hartmark Aug 27, 2022
d4a5163
Fix test running in mono (.net framework on linux)
hartmark Aug 27, 2022
2b89f9c
made JsonSerializerFactory non-static
Aug 28, 2022
a6b8fa6
Update and rename JsonSerializerFactory.cs to DefaultJsonSerializerFa…
abatishchev Sep 8, 2022
b5b2e3c
Create IJsonSerializerFactory.cs
abatishchev Sep 8, 2022
6f57e14
Update IJsonSerializerFactory.cs
abatishchev Sep 8, 2022
c1c8171
Update DefaultJsonSerializerFactory.cs
abatishchev Sep 8, 2022
2f51d22
Create DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
52a22c1
Update DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
2a994f7
Update ServiceCollectionExtensions.cs
abatishchev Sep 8, 2022
6d933cd
Update JwtBuilder.cs
abatishchev Sep 8, 2022
15b6952
Update DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
171ac0a
Update DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
b21bb1f
Update DelegateAlgorithmFactory.cs
abatishchev Sep 8, 2022
c8001a7
Update DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
bd57102
Update DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
f5db345
Update DefaultJsonSerializerFactory.cs
abatishchev Sep 8, 2022
ffc16cc
Update DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
b7713ce
Update DelegateJsonSerializerFactory.cs
abatishchev Sep 8, 2022
7f6fc45
Update JwtBuilder.cs
abatishchev Sep 8, 2022
024265d
Update JwtBuilder.cs
abatishchev Sep 8, 2022
9945642
Update JwtBuilderEncodeTests.cs
abatishchev Sep 8, 2022
cf59026
Update JwtDecoderTests.cs
abatishchev Sep 8, 2022
b9e0d92
Update SerializerTests.cs
abatishchev Sep 8, 2022
5437103
Update JwtEncoderTests.cs
abatishchev Sep 8, 2022
b604fac
Update SerializerTests.cs
abatishchev Sep 8, 2022
82fe9c5
Update JwtBuilder.cs
abatishchev Sep 8, 2022
adc1d66
Update JwtBuilder.cs
abatishchev Sep 8, 2022
dd65918
Update and rename SerializerTests.cs to DefaultJsonSerializerFactoryT…
abatishchev Sep 8, 2022
b7a9cea
Update JwtValidatorTests.cs
abatishchev Sep 8, 2022
8d314cd
Update DefaultJsonSerializerFactory.cs
abatishchev Sep 8, 2022
54299a5
Update DefaultJsonSerializerFactoryTests.cs
abatishchev Sep 8, 2022
da82a6c
Update JwtBuilderEncodeTests.cs
abatishchev Sep 8, 2022
027cb83
Update JwtBuilderDecodeTests.cs
abatishchev Sep 8, 2022
bf981de
Update JwtValidatorTests.cs
abatishchev Sep 8, 2022
d7bf51e
Update JwtSecurityTests.cs
abatishchev Sep 8, 2022
440da08
Update JwtBuilderDecodeTests.cs
abatishchev Sep 8, 2022
888c0c1
Update JwtAuthenticationHandlerTests.cs
abatishchev Sep 8, 2022
42155c8
Update JwtBuilderDecodeTests.cs
abatishchev Sep 8, 2022
2780209
Update JwtAuthenticationHandlerTests.cs
abatishchev Sep 8, 2022
fa7c10a
Update ServiceCollectionExtensions.cs
abatishchev Sep 8, 2022
4f18830
Update ServiceCollectionExtensions.cs
abatishchev Sep 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions src/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,8 @@
<Choose>
<When Condition="'$(TargetFramework)' == 'net462' OR '$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'net6.0'">
<PropertyGroup>
<DefineConstants>$(DefineConstants);SYSTEM_TEXT_JSON</DefineConstants>
<DefineConstants>$(DefineConstants);MODERN_DOTNET</DefineConstants>
abatishchev marked this conversation as resolved.
Show resolved Hide resolved
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<DefineConstants>$(DefineConstants);NEWTONSOFT_JSON</DefineConstants>
</PropertyGroup>
</Otherwise>
</Choose>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Authors>Alexander Batishchev</Authors>
<PackageTags>jwt;json;asp.net;asp.net core;.net core;authorization</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>10.0.0-beta3</Version>
<Version>10.0.0-beta4</Version>
<FileVersion>10.0.0.0</FileVersion>
<AssemblyVersion>10.0.0.0</AssemblyVersion>
<RootNamespace>JWT.Extensions.AspNetCore</RootNamespace>
Expand All @@ -30,8 +30,8 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Condition="$(DefineConstants.Contains(SYSTEM_TEXT_JSON))" Include="System.Text.Json" Version="6.0.4" />
<PackageReference Condition="$(DefineConstants.Contains(NEWTONSOFT_JSON))" Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Condition="$(DefineConstants.Contains(MODERN_DOTNET))" Include="System.Text.Json" Version="6.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Authors>Alexander Batishchev</Authors>
<PackageTags>jwt;json;asp.net;asp.net core;.net core;authorization;dependenсy injection</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>2.2.0-beta3</Version>
<Version>2.2.0-beta4</Version>
<FileVersion>2.0.0.0</FileVersion>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<RootNamespace>JWT</RootNamespace>
Expand All @@ -30,8 +30,8 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.25" />
<PackageReference Condition="$(DefineConstants.Contains(SYSTEM_TEXT_JSON))" Include="System.Text.Json" Version="6.0.4" />
<PackageReference Condition="$(DefineConstants.Contains(NEWTONSOFT_JSON))" Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Condition="$(DefineConstants.Contains(MODERN_DOTNET))" Include="System.Text.Json" Version="6.0.4" />
hartmark marked this conversation as resolved.
Show resolved Hide resolved
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
using System;
using JWT.Algorithms;
using JWT.Internal;
using JWT.Serializers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

#if SYSTEM_TEXT_JSON
using JsonSerializer = JWT.Serializers.SystemTextSerializer;
#elif NEWTONSOFT_JSON
using JsonSerializer = JWT.Serializers.JsonNetSerializer;
#endif

namespace JWT
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddJwtEncoder(this IServiceCollection services)
{
services.TryAddSingleton<IJwtEncoder, JwtEncoder>();
services.TryAddSingleton<IJsonSerializer, JsonSerializer>();
services.TryAddSingleton<IJsonSerializerFactory, DefaultJsonSerializerFactory>();
services.TryAddSingleton<IJsonSerializer>(p => p.GetRequiredService<IJsonSerializerFactory>().Create());
services.TryAddSingleton<IBase64UrlEncoder, JwtBase64UrlEncoder>();

return services;
Expand All @@ -44,7 +40,8 @@ private static IServiceCollection AddJwtEncoder<TFactory>(this IServiceCollectio
public static IServiceCollection AddJwtDecoder(this IServiceCollection services)
{
services.TryAddSingleton<IJwtDecoder, JwtDecoder>();
services.TryAddSingleton<IJsonSerializer, JsonSerializer>();
services.TryAddSingleton<IJsonSerializerFactory, DefaultJsonSerializerFactory>();
services.TryAddSingleton<IJsonSerializer>(p => p.GetRequiredService<IJsonSerializerFactory>().Create());
services.TryAddSingleton<IJwtValidator, JwtValidator>();
services.TryAddSingleton<IBase64UrlEncoder, JwtBase64UrlEncoder>();
services.TryAddSingleton<IDateTimeProvider, UtcDatetimeProvider>();
Expand All @@ -60,4 +57,4 @@ public static IServiceCollection AddJwtDecoder<TFactory>(this IServiceCollection
return services.AddJwtDecoder();
}
}
}
}
7 changes: 3 additions & 4 deletions src/JWT/Algorithms/DelegateAlgorithmFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ public DelegateAlgorithmFactory(Func<IJwtAlgorithm> algFactory) =>
/// Creates an instance of <see cref="DelegateAlgorithmFactory" /> with supplied algorithm.
/// </summary>
/// <exception cref="ArgumentNullException" />
public DelegateAlgorithmFactory(IJwtAlgorithm algorithm)
public DelegateAlgorithmFactory(IJwtAlgorithm algorithm) :
this(() => algorithm)
{
if (algorithm is null)
throw new ArgumentNullException(nameof(algorithm));

_algFactory = () => algorithm;
}

/// <inheritdoc />
public IJwtAlgorithm Create(JwtDecoderContext context) =>
_algFactory();
}
}
}
69 changes: 44 additions & 25 deletions src/JWT/Builder/JwtBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
using System.Linq;
using System.Reflection;
using JWT.Algorithms;

using JWT.Serializers;
using static JWT.Internal.EncodingHelper;
using static JWT.Serializers.JsonSerializerFactory;

namespace JWT.Builder
{
Expand All @@ -19,7 +18,8 @@ public sealed class JwtBuilder
private IJwtDecoder _decoder;
private IJwtValidator _validator;

private IJsonSerializer _serializer = CreateSerializer();
private IJsonSerializerFactory _jsonSerializerFactory = new DefaultJsonSerializerFactory();

private IBase64UrlEncoder _urlEncoder = new JwtBase64UrlEncoder();
private IDateTimeProvider _dateTimeProvider = new UtcDateTimeProvider();
private ValidationParameters _valParams = ValidationParameters.Default;
Expand Down Expand Up @@ -75,9 +75,23 @@ public JwtBuilder AddClaim(string name, object value)
/// Sets JWT serializer.
/// </summary>
/// <returns>Current builder instance</returns>
public JwtBuilder WithSerializer(IJsonSerializer serializer)
public JwtBuilder WithJsonSerializer(IJsonSerializer serializer) =>
WithJsonSerializerFactory(new DelegateJsonSerializerFactory(serializer));

/// <summary>
/// Sets JWT serializer.
/// </summary>
/// <returns>Current builder instance</returns>
public JwtBuilder WithJsonSerializer(Func<IJsonSerializer> factory) =>
WithJsonSerializerFactory(new DelegateJsonSerializerFactory(factory));

/// <summary>
/// Sets JWT serializer factory.
/// </summary>
/// <returns>Current builder instance</returns>
public JwtBuilder WithJsonSerializerFactory(IJsonSerializerFactory jsonSerializerFactory)
{
_serializer = serializer;
_jsonSerializerFactory = jsonSerializerFactory;
return this;
}

Expand Down Expand Up @@ -321,55 +335,60 @@ private void TryCreateEncoder()
{
if (_algorithm is null && _algFactory is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtEncoder)}. Call {nameof(WithAlgorithm)}.");
if (_serializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtEncoder)}. Call {nameof(WithSerializer)}");

var jsonSerializer = _jsonSerializerFactory.Create();
if (jsonSerializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtEncoder)}. Call {nameof(WithJsonSerializer)}");
if (_urlEncoder is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtEncoder)}. Call {nameof(WithUrlEncoder)}.");

if (_algorithm is object)
_encoder = new JwtEncoder(_algorithm, _serializer, _urlEncoder);
_encoder = new JwtEncoder(_algorithm, jsonSerializer, _urlEncoder);
else if (_algFactory is object)
_encoder = new JwtEncoder(_algFactory, _serializer, _urlEncoder);
_encoder = new JwtEncoder(_algFactory, jsonSerializer, _urlEncoder);
}

private void TryCreateDecoder()
{
TryCreateValidator();

if (_serializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtDecoder)}. Call {nameof(WithSerializer)}.");
var jsonSerializer = _jsonSerializerFactory.Create();
if (jsonSerializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtDecoder)}. Call {nameof(WithJsonSerializer)}.");
if (_urlEncoder is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtDecoder)}. Call {nameof(WithUrlEncoder)}.");

if (_algorithm is object)
_decoder = new JwtDecoder(_serializer, _validator, _urlEncoder, _algorithm);
_decoder = new JwtDecoder(jsonSerializer, _validator, _urlEncoder, _algorithm);
else if (_algFactory is object)
_decoder = new JwtDecoder(_serializer, _validator, _urlEncoder, _algFactory);
_decoder = new JwtDecoder(jsonSerializer, _validator, _urlEncoder, _algFactory);
else if (!_valParams.ValidateSignature)
_decoder = new JwtDecoder(_serializer, _urlEncoder);
_decoder = new JwtDecoder(jsonSerializer, _urlEncoder);
}

private void TryCreateDecoderForHeader()
{
if (_serializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtDecoder)}. Call {nameof(WithSerializer)}.");
var jsonSerializer = _jsonSerializerFactory.Create();
if (jsonSerializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtDecoder)}. Call {nameof(WithJsonSerializer)}.");
if (_urlEncoder is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtDecoder)}. Call {nameof(WithUrlEncoder)}.");

_decoder = new JwtDecoder(_serializer, _urlEncoder);
_decoder = new JwtDecoder(jsonSerializer, _urlEncoder);
}

private void TryCreateValidator()
{
if (_validator is object)
return;

if (_serializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtValidator)}. Call {nameof(WithSerializer)}.");
var jsonSerializer = _jsonSerializerFactory.Create();
if (jsonSerializer is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtValidator)}. Call {nameof(WithJsonSerializer)}.");
if (_dateTimeProvider is null)
throw new InvalidOperationException($"Can't instantiate {nameof(JwtValidator)}. Call {nameof(WithDateTimeProvider)}.");

_validator = new JwtValidator(_serializer, _dateTimeProvider, _valParams);
_validator = new JwtValidator(jsonSerializer, _dateTimeProvider, _valParams);
}

private void EnsureCanEncode()
Expand All @@ -382,7 +401,7 @@ private void EnsureCanEncode()
throw new InvalidOperationException(
"Can't encode a token. Check if you have called all of the following methods:" + Environment.NewLine +
$"-{nameof(WithAlgorithm)}" + Environment.NewLine +
$"-{nameof(WithSerializer)}" + Environment.NewLine +
$"-{nameof(WithJsonSerializer)}" + Environment.NewLine +
$"-{nameof(WithUrlEncoder)}.");
}
}
Expand All @@ -396,7 +415,7 @@ private void EnsureCanDecode()
{
throw new InvalidOperationException(
"Can't decode a token. Check if you have called all of the following methods:" + Environment.NewLine +
$"-{nameof(WithSerializer)}" + Environment.NewLine +
$"-{nameof(WithJsonSerializer)}" + Environment.NewLine +
$"-{nameof(WithValidator)}" + Environment.NewLine +
$"-{nameof(WithUrlEncoder)}.");
}
Expand All @@ -411,7 +430,7 @@ private void EnsureCanDecodeHeader()
{
throw new InvalidOperationException(
"Can't decode a token header. Check if you have called all of the following methods:" + Environment.NewLine +
$"-{nameof(WithSerializer)}" + Environment.NewLine +
$"-{nameof(WithJsonSerializer)}" + Environment.NewLine +
$"-{nameof(WithUrlEncoder)}.");
}
}
Expand All @@ -421,7 +440,7 @@ private void EnsureCanDecodeHeader()
/// </summary>
private bool CanEncode() =>
(_algorithm is object || _algFactory is object) &&
_serializer is object &&
_jsonSerializerFactory is object &&
_urlEncoder is object &&
_jwt.Payload is object;

Expand All @@ -444,7 +463,7 @@ private bool CanDecodeHeader()
if (_urlEncoder is null)
return false;

if (_serializer is null)
if (_jsonSerializerFactory is null)
return false;

return true;
Expand Down
4 changes: 2 additions & 2 deletions src/JWT/Builder/JwtHeader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#if SYSTEM_TEXT_JSON
#if MODERN_DOTNET
using JsonProperty = System.Text.Json.Serialization.JsonPropertyNameAttribute;
#elif NEWTONSOFT_JSON
#else
using Newtonsoft.Json;
#endif

Expand Down
6 changes: 3 additions & 3 deletions src/JWT/JWT.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<Authors>Alexander Batishchev, John Sheehan, Michael Lehenbauer</Authors>
<PackageTags>jwt;json;authorization</PackageTags>
<PackageLicenseExpression>CC0-1.0</PackageLicenseExpression>
<Version>10.0.0-beta6</Version>
<Version>10.0.0-beta7</Version>
<FileVersion>10.0.0.0</FileVersion>
<AssemblyVersion>10.0.0.0</AssemblyVersion>
<RootNamespace>JWT</RootNamespace>
Expand All @@ -38,8 +38,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Condition="$(DefineConstants.Contains(SYSTEM_TEXT_JSON))" Include="System.Text.Json" Version="6.0.4" />
<PackageReference Condition="$(DefineConstants.Contains(NEWTONSOFT_JSON))" Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Condition="$(DefineConstants.Contains(MODERN_DOTNET))" Include="System.Text.Json" Version="6.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3' OR '$(TargetFramework)' == 'netstandard2.0'">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#if SYSTEM_TEXT_JSON
#if MODERN_DOTNET
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down
19 changes: 19 additions & 0 deletions src/JWT/Serializers/DefaultJsonSerializerFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace JWT.Serializers
{
public sealed class DefaultJsonSerializerFactory : IJsonSerializerFactory
{
private readonly IJsonSerializer _jsonSerializer;

public DefaultJsonSerializerFactory()
{
#if MODERN_DOTNET
_jsonSerializer = new SystemTextSerializer();
#else
_jsonSerializer = new JsonNetSerializer();
#endif
}

public IJsonSerializer Create() =>
_jsonSerializer;
}
}
29 changes: 29 additions & 0 deletions src/JWT/Serializers/DelegateJsonSerializerFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;

namespace JWT.Serializers
{
internal sealed class DelegateJsonSerializerFactory : IJsonSerializerFactory
{
private readonly Func<IJsonSerializer> _factory;

public DelegateJsonSerializerFactory(IJsonSerializer jsonSerializer) :
this(() => jsonSerializer)
{
if (jsonSerializer is null)
throw new ArgumentNullException(nameof(jsonSerializer));
}

public DelegateJsonSerializerFactory(IJsonSerializerFactory factory) :
this(() => factory.Create())
{
if (factory is null)
throw new ArgumentNullException(nameof(factory));
}

public DelegateJsonSerializerFactory(Func<IJsonSerializer> factory) =>
_factory = factory ?? throw new ArgumentNullException(nameof(factory));

public IJsonSerializer Create() =>
_factory();
}
}
7 changes: 7 additions & 0 deletions src/JWT/Serializers/IJsonSerializerFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace JWT.Serializers
{
public interface IJsonSerializerFactory
{
IJsonSerializer Create();
}
}
4 changes: 1 addition & 3 deletions src/JWT/Serializers/JsonNetSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#if NEWTONSOFT_JSON
using System;
using System;
using System.IO;
using System.Text;
using Newtonsoft.Json;
Expand Down Expand Up @@ -61,4 +60,3 @@ public object Deserialize(Type type, string json)
}
}
}
#endif
Loading