Skip to content

Commit

Permalink
Making JwtEncoder.Validate() public (#128)
Browse files Browse the repository at this point in the history
* Refactoring JwtDecoder.Validate(), making it public. Adding xml doc 
* Bumping version to 3.0.1

Resolves #126

* Refactoring JwtDecoder.Validate(). Adding xml doc

* Renaming security tests

* Bumping version to 3.0.1
  • Loading branch information
abatishchev authored Jul 24, 2017
1 parent d1d3311 commit 8432419
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
4 changes: 3 additions & 1 deletion src/JWT/JWT.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
<PackageProjectUrl>https://github.com/jwt-dotnet/jwt</PackageProjectUrl>
<Authors>John Sheehan, Michael Lehenbauer, Alexander Batishchev</Authors>
<PackageLicenseUrl>https://creativecommons.org/publicdomain/zero/1.0/</PackageLicenseUrl>
<Version>3.0.0</Version>
<Version>3.0.1</Version>
<PackageTags>jwt json</PackageTags>
<FileVersion>3.0.1.0</FileVersion>
<AssemblyVersion>3.0.0.0</AssemblyVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand Down
14 changes: 11 additions & 3 deletions src/JWT/JwtDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public string Decode(string token, byte[] key, bool verify)

if (verify)
{
Validate(payload, payloadJson, parts, key);
Validate(parts, key);
}

return payloadJson;
Expand Down Expand Up @@ -95,7 +95,12 @@ public T DecodeToObject<T>(string token, byte[] key, bool verify)
return _jsonSerializer.Deserialize<T>(payloadJson);
}

private void Validate(string payload, string payloadJson, string[] parts, byte[] key)
/// <summary>
/// Helper method that prepares data before calling <see cref="IJwtValidator.Validate" />.
/// </summary>
/// <param name="parts">The JWT split into parts.</param>
/// <param name="key">The key that was used to sign the JWT.</param>
public void Validate(string[] parts, byte[] key)
{
var crypto = _urlEncoder.Decode(parts[2]);
var decodedCrypto = Convert.ToBase64String(crypto);
Expand All @@ -104,6 +109,9 @@ private void Validate(string payload, string payloadJson, string[] parts, byte[]
var headerJson = Encoding.UTF8.GetString(_urlEncoder.Decode(header));
var headerData = _jsonSerializer.Deserialize<Dictionary<string, object>>(headerJson);

var payload = parts[1];
var payloadJson = Encoding.UTF8.GetString(_urlEncoder.Decode(payload));

var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));

var algName = (string)headerData["alg"];
Expand All @@ -115,4 +123,4 @@ private void Validate(string payload, string payloadJson, string[] parts, byte[]
_jwtValidator.Validate(payloadJson, decodedCrypto, decodedSignature);
}
}
}
}
32 changes: 13 additions & 19 deletions tests/JWT.Tests.Core/JwtSecurityTest.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using FluentAssertions;
using System;
using System.Security.Cryptography.X509Certificates;
using FluentAssertions;
using JWT.Algorithms;
using JWT.Serializers;
using JWT.Tests.Common;
using System;
using System.Security.Cryptography.X509Certificates;
using Xunit;

namespace JWT.Tests.Core
Expand All @@ -12,7 +12,7 @@ public class JwtSecurityTest
{
[Fact]
[Trait(TestCategory.Category, TestCategory.Security)]
public void Algorithm_None_Should_Throw_Exception()
public void Decode_Should_Throw_Exception_When_Non_Algorithm_Was_Used()
{
var serializer = new JsonNetSerializer();
var validator = new JwtValidator(serializer, new UtcDateTimeProvider());
Expand All @@ -26,27 +26,21 @@ public void Algorithm_None_Should_Throw_Exception()

[Fact]
[Trait(TestCategory.Category, TestCategory.Security)]
public void HMAC_Decoding_When_Expecting_RSA_Should_Fail()
public void Decode_Should_Throw_Exception_When_HMA_Algorithm_Is_Used_But_RSA_Was_Expected()
{
var serializer = new JsonNetSerializer();
var urlEncoder = new JwtBase64UrlEncoder();
var HMACencoder = new JwtEncoder(new HMACSHA256Algorithm(), serializer, urlEncoder);
var encoder = new JwtEncoder(new HMACSHA256Algorithm(), serializer, urlEncoder);

var HMACEncodedToken = HMACencoder.Encode(TestData.Customer, TestData.ServerRSAPublicKey);
var encodedToken = encoder.Encode(TestData.Customer, TestData.ServerRSAPublicKey);

// RSA Decoder
var validator = new JwtValidator(serializer, new UtcDateTimeProvider());
var RSAFactory = new RSAlgorithmFactory(GetRSAPublicKeyAsCertificate);
var decoder = new JwtDecoder(serializer, validator, urlEncoder, RSAFactory);

Action action = () => decoder.Decode(HMACEncodedToken, TestData.ServerRSAPublicKey, verify: true);
var algFactory = new RSAlgorithmFactory(() => new X509Certificate2(TestData.ServerRSAPublicKey));
var decoder = new JwtDecoder(serializer, validator, urlEncoder, algFactory);

action.ShouldThrow<NotSupportedException>("because HMAC Tokens can be forged in RSA Decoder");
}

private X509Certificate2 GetRSAPublicKeyAsCertificate()
{
return new X509Certificate2(TestData.ServerRSAPublicKey);
Action action = () => decoder.Decode(encodedToken, TestData.ServerRSAPublicKey, verify: true);

action.ShouldThrow<NotSupportedException>("Because HMAC Tokens can be forged in RSA Decoder");
}
}
}
}

0 comments on commit 8432419

Please sign in to comment.