Skip to content

Commit

Permalink
NoneAlgorithm should not require any keys as it is not signed (#435)
Browse files Browse the repository at this point in the history
* NoneAlgorithm should not require any keys as it is not signed
* Updated tests
* Bumped version of JWT to 10.0.0-beta8

Co-authored-by: Alexander Batishchev <[email protected]>
  • Loading branch information
hartmark and abatishchev authored Sep 8, 2022
1 parent 2e2c9c0 commit 0381094
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 13 deletions.
2 changes: 1 addition & 1 deletion 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-beta7</Version>
<Version>10.0.0-beta8</Version>
<FileVersion>10.0.0.0</FileVersion>
<AssemblyVersion>10.0.0.0</AssemblyVersion>
<RootNamespace>JWT</RootNamespace>
Expand Down
2 changes: 1 addition & 1 deletion src/JWT/JwtEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public string Encode(IDictionary<string, object> extraHeaders, object payload, b
var algorithm = _algFactory.Create(null);
if (algorithm is null)
throw new ArgumentNullException(nameof(algorithm));
if (!algorithm.IsAsymmetric() && key is null)
if (!algorithm.IsAsymmetric() && key is null && algorithm is not NoneAlgorithm)
throw new ArgumentNullException(nameof(key));

var header = extraHeaders is null ?
Expand Down
11 changes: 11 additions & 0 deletions tests/JWT.Tests.Common/Builder/JwtBuilderDecodeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ public void Decode_With_MustVerifySignature_Should_Not_Be_Allowed_For_For_None_A
.Throw<InvalidOperationException>("verify signature is not supported for none algorithm");
}

[TestMethod]
public void Decode_Using_No_Secret_Should_Work_For_None_Algorithm()
{
var token = JwtBuilder.Create()
.WithAlgorithm(new NoneAlgorithm())
.Decode(TestData.TokenWithAlgNoneMissingSignature);

token.Should()
.NotBeNullOrEmpty("Using none algorithm should be valid without any secret");
}

[TestMethod]
public void Decode_With_VerifySignature_And_Without_Algorithm_Should_Throw_Exception()
{
Expand Down
20 changes: 19 additions & 1 deletion tests/JWT.Tests.Common/Builder/JwtBuilderEncodeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public void Encode_With_MultipleSecrets_Should_Throw_Exception()
}

[TestMethod]
public void Encode_WithoutAlgorithm_Should_Return_Token()
public void Encode_With_NoneAlgorithm_Should_Return_Token()
{
var secret = _fixture.Create<string>();

Expand All @@ -158,6 +158,24 @@ public void Encode_WithoutAlgorithm_Should_Return_Token()
.Should()
.BeEmpty("Because it should miss signature");
}

[TestMethod]
public void Encode_With_NoneAlgorithm_Should_Not_Require_Secret()
{
var token = JwtBuilder.Create()
.WithAlgorithm(new NoneAlgorithm())
.Encode();

token.Should()
.NotBeNullOrEmpty("because the token should contains some data");
token.Split('.')
.Should()
.HaveCount(3, "because the token should consist of three parts");
token.Split('.')
.Last()
.Should()
.BeEmpty("Because it should miss signature");
}

[TestMethod]
public void Encode_Should_Return_Token_With_Extra_Headers()
Expand Down
37 changes: 27 additions & 10 deletions tests/JWT.Tests.Common/JwtEncoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ public class JwtEncoderTests
public void Encode_Should_Encode_To_Token()
{
const string key = TestData.Secret;
var toEncode = TestData.Customer;
var customer = TestData.Customer;
const string expected = TestData.Token;

var algorithm = new HMACSHA256Algorithm();
var urlEncoder = new JwtBase64UrlEncoder();
var serializer = CreateSerializer();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

var actual = encoder.Encode(toEncode, key);
var actual = encoder.Encode(customer, key);

actual.Should()
.Be(expected, "because the same data encoded with the same key must result in the same token");
Expand All @@ -36,15 +36,15 @@ public void Encode_Should_Encode_To_Token_With_Extra_Headers()
{ "foo", "bar" }
};
const string key = TestData.Secret;
var toEncode = TestData.Customer;
var customer = TestData.Customer;
const string expected = TestData.TokenWithExtraHeaders;

var algorithm = new HMACSHA256Algorithm();
var urlEncoder = new JwtBase64UrlEncoder();
var serializer = CreateSerializer();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

var actual = encoder.Encode(extraHeaders, toEncode, key);
var actual = encoder.Encode(extraHeaders, customer, key);

actual.Should()
.Be(expected, "because the same data encoded with the same key must result in the same token");
Expand All @@ -58,15 +58,15 @@ public void Encode_Should_Encode_To_Token_With_Custom_Type_Headers()
{ "typ", "foo" }
};
const string key = TestData.Secret;
var toEncode = TestData.Customer;
var customer = TestData.Customer;
const string expected = TestData.TokenWithCustomTypeHeader;

var algorithm = new HMACSHA256Algorithm();
var urlEncoder = new JwtBase64UrlEncoder();
var serializer = CreateSerializer();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

var actual = encoder.Encode(extraHeaders, toEncode, key);
var actual = encoder.Encode(extraHeaders, customer, key);

actual.Should()
.Be(expected, "because the same data encoded with the same key must result in the same token");
Expand All @@ -76,15 +76,15 @@ public void Encode_Should_Encode_To_Token_With_Custom_Type_Headers()
public void Encode_With_NoAlgorithm_Should_Encode_To_Token()
{
const string key = TestData.Secret;
var toEncode = TestData.Customer;
var customer = TestData.Customer;
const string expected = TestData.TokenWithoutSignature;

var algorithm = new NoneAlgorithm();
var urlEncoder = new JwtBase64UrlEncoder();
var serializer = CreateSerializer();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

var actual = encoder.Encode(toEncode, key);
var actual = encoder.Encode(customer, key);

actual.Should()
.Be(expected, "because the same data encoded with the same key must result in the same token");
Expand All @@ -94,21 +94,38 @@ public void Encode_With_NoAlgorithm_Should_Encode_To_Token()
public void Encode_Should_Encode_To_Token_Using_Json_Net()
{
const string key = TestData.Secret;
var toEncode = TestData.Customer;
var customer = TestData.Customer;
const string expected = TestData.Token;

var algorithm = new HMACSHA256Algorithm();
var urlEncoder = new JwtBase64UrlEncoder();
var serializer = new JsonNetSerializer();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

var actual = encoder.Encode(toEncode, key);
var actual = encoder.Encode(customer, key);

actual.Should()
.Be(expected, "because the same data encoded with the same key must result in the same token");
}

private static IJsonSerializer CreateSerializer() =>
new DefaultJsonSerializerFactory().Create();

[TestMethod]
public void Encode_With_NoAlgorithm_Should_Encode_To_Token_Not_Needing_Secret()
{
var customer = TestData.Customer;
const string expected = TestData.TokenWithoutSignature;

var algorithm = new NoneAlgorithm();
var urlEncoder = new JwtBase64UrlEncoder();
var serializer = CreateSerializer();
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

var actual = encoder.Encode(customer, (string)null);

actual.Should()
.Be(expected, "because the same data encoded with the same key must result in the same token");
}
}
}

0 comments on commit 0381094

Please sign in to comment.