diff --git a/src/JWT/JWT.csproj b/src/JWT/JWT.csproj index 24be8d62f..5734d2cc4 100644 --- a/src/JWT/JWT.csproj +++ b/src/JWT/JWT.csproj @@ -21,7 +21,7 @@ https://github.com/jwt-dotnet/jwt John Sheehan, Michael Lehenbauer, Alexander Batishchev https://creativecommons.org/publicdomain/zero/1.0/ - 3.0.0-beta2 + 3.0.0-beta3 jwt json diff --git a/src/JWT/JsonWebToken.cs b/src/JWT/JsonWebToken.cs deleted file mode 100644 index 6ffc5c49c..000000000 --- a/src/JWT/JsonWebToken.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using JWT.Algorithms; -using JWT.Serializers; - -namespace JWT -{ - /// - /// Provides methods for encoding and decoding JSON Web Tokens. - /// - [Obsolete(ObsoleteMessage)] - public static class JsonWebToken - { - private const string ObsoleteMessage = "Static API is obsolete as of version 2.0 and will be removed in a future version."; - - /// - /// Pluggable JSON Serializer - /// - public static IJsonSerializer JsonSerializer = new JsonNetSerializer(); - - private static readonly IJwtValidator _jwtValidator = new JwtValidator(JsonSerializer, new UtcDateTimeProvider()); - - private static readonly IAlgorithmFactory _hmacshaAlgorithmFactory = new HMACSHAAlgorithmFactory(); - - private static readonly IBase64UrlEncoder _urlEncoder = new JwtBase64UrlEncoder(); - - /// - /// Creates a JWT given a payload, the signing key, and the algorithm to use. - /// - /// An arbitrary payload (must be serializable to JSON). - /// The key used to sign the token. - /// The hash algorithm to use. - /// The generated JWT. - public static string Encode(object payload, string key, JwtHashAlgorithm algorithm) - { - return Encode(new Dictionary(), payload, Encoding.UTF8.GetBytes(key), algorithm); - } - - /// - /// Creates a JWT given a payload, the signing key, and the algorithm to use. - /// - /// An arbitrary payload (must be serializable to JSON). - /// The key used to sign the token. - /// The hash algorithm to use. - /// The generated JWT. - public static string Encode(object payload, byte[] key, JwtHashAlgorithm algorithm) - { - return Encode(new Dictionary(), payload, key, algorithm); - } - - /// - /// Creates a JWT given a set of arbitrary extra headers, a payload, the signing key, and the algorithm to use. - /// - /// An arbitrary set of extra headers. Will be augmented with the standard "typ" and "alg" headers. - /// An arbitrary payload (must be serializable to JSON). - /// The key bytes used to sign the token. - /// The hash algorithm to use. - /// The generated JWT. - public static string Encode(IDictionary extraHeaders, object payload, string key, JwtHashAlgorithm algorithm) - { - return Encode(extraHeaders, payload, Encoding.UTF8.GetBytes(key), algorithm); - } - - /// - /// Creates a JWT given a header, a payload, the signing key, and the algorithm to use. - /// - /// An arbitrary set of extra headers. Will be augmented with the standard "typ" and "alg" headers. - /// An arbitrary payload (must be serializable to JSON). - /// The key bytes used to sign the token. - /// The hash algorithm to use. - /// The generated JWT. - public static string Encode(IDictionary extraHeaders, object payload, byte[] key, JwtHashAlgorithm algorithm) - { - return new JwtEncoder( - _hmacshaAlgorithmFactory.Create(algorithm), - JsonSerializer, - _urlEncoder) - .Encode(extraHeaders, payload, key); - } - - /// - /// Given a JWT, decode it and return the JSON payload. - /// - /// The JWT. - /// The key that was used to sign the JWT. - /// Whether to verify the signature (default is true). - /// A string containing the JSON payload. - /// Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm. - /// Thrown if the verify parameter was true and the token has an expired exp claim. - public static string Decode(string token, string key, bool verify = true) - { - return Decode(token, Encoding.UTF8.GetBytes(key), verify); - } - - /// - /// Given a JWT, decode it and return the JSON payload. - /// - /// The JWT. - /// The key bytes that were used to sign the JWT. - /// Whether to verify the signature (default is true). - /// A string containing the JSON payload. - /// Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm. - /// Thrown if the verify parameter was true and the token has an expired exp claim. - public static string Decode(string token, byte[] key, bool verify = true) - { - return new JwtDecoder( - JsonSerializer, - _jwtValidator, - _urlEncoder) - .Decode(token, key, verify); - } - - /// - /// Given a JWT, decode it and return the payload as an object. - /// - /// The JWT. - /// The key that was used to sign the JWT. - /// Whether to verify the signature (default is true). - /// An object representing the payload. - /// Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm. - /// Thrown if the verify parameter was true and the token has an expired exp claim. - public static object DecodeToObject(string token, string key, bool verify = true) - { - return DecodeToObject(token, Encoding.UTF8.GetBytes(key), verify); - } - - /// - /// Given a JWT, decode it and return the payload as an object. - /// - /// The JWT. - /// The key that was used to sign the JWT. - /// Whether to verify the signature (default is true). - /// An object representing the payload. - /// Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm. - /// Thrown if the verify parameter was true and the token has an expired exp claim. - public static object DecodeToObject(string token, byte[] key, bool verify = true) - { - var payloadJson = Decode(token, key, verify); - return JsonSerializer.Deserialize>(payloadJson); - } - - /// - /// Given a JWT, decode it and return the payload as an object. - /// - /// The to return - /// The JWT. - /// The key that was used to sign the JWT. - /// Whether to verify the signature (default is true). - /// An object representing the payload. - /// Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm. - /// Thrown if the verify parameter was true and the token has an expired exp claim. - public static T DecodeToObject(string token, string key, bool verify = true) - { - return DecodeToObject(token, Encoding.UTF8.GetBytes(key), verify); - } - - /// - /// Given a JWT, decode it and return the payload as an object. - /// - /// The to return - /// The JWT. - /// The key that was used to sign the JWT. - /// Whether to verify the signature (default is true). - /// An object representing the payload. - /// Thrown if the verify parameter was true and the signature was NOT valid or if the JWT was signed with an unsupported algorithm. - /// Thrown if the verify parameter was true and the token has an expired exp claim. - public static T DecodeToObject(string token, byte[] key, bool verify = true) - { - var payloadJson = Decode(token, key, verify); - return JsonSerializer.Deserialize(payloadJson); - } - - /// - /// Given the JWT, verifies it. - /// - /// >An arbitrary payload (already serialized to JSON). - /// Decoded body - /// Decoded signature - /// The signature is invalid. - /// The token has expired. - public static void Verify(string payloadJson, string decodedCrypto, string decodedSignature) - { - _jwtValidator.Validate(payloadJson, decodedCrypto, decodedSignature); - } - - /// From JWT spec - public static string Base64UrlEncode(byte[] input) - { - return _urlEncoder.Encode(input); - } - - /// From JWT spec - public static byte[] Base64UrlDecode(string input) - { - return _urlEncoder.Decode(input); - } - } -} diff --git a/tests/JWT.Tests.Core/DecodeTests.cs b/tests/JWT.Tests.Core/DecodeTests.cs deleted file mode 100644 index 60296079d..000000000 --- a/tests/JWT.Tests.Core/DecodeTests.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using FluentAssertions; -using JWT.Serializers; -using Xunit; -using JWT.Tests.Common; - -namespace JWT.Tests -{ - public class DecodeTests - { - [Fact] - public void Decode_Should_DecodeToken_To_Json_Encoded_String_With_JsonNet_Serializer() - { - var serializer = new JsonNetSerializer(); - JsonWebToken.JsonSerializer = serializer; - - var expectedPayload = serializer.Serialize(TestData.Customer); - var actualPayload = JsonWebToken.Decode(TestData.Token, "ABC", verify: false); - - actualPayload.Should().Be(expectedPayload); - } - - [Fact] - public void DecodeToObject_Should_DecodeToken_To_Dictionary_With_JsonNet_Serializer() - { - JsonWebToken.JsonSerializer = new JsonNetSerializer(); - - var actualPayload = JsonWebToken.DecodeToObject(TestData.Token, "ABC", verify: false); - - actualPayload.ShouldBeEquivalentTo(TestData.DictionaryPayload, options => options.IncludingAllRuntimeProperties()); - } - - [Fact] - public void DecodeToObject_Should_DecodeToken_To_Generic_Type_With_JsonNet_Serializer() - { - JsonWebToken.JsonSerializer = new JsonNetSerializer(); - - var actualPayload = JsonWebToken.DecodeToObject(TestData.Token, "ABC", verify: false); - - actualPayload.ShouldBeEquivalentTo(TestData.Customer); - } - - [Fact] - public void DecodeToObject_Should_Throw_Exception_On_MalformedToken() - { - Action action = () => JsonWebToken.DecodeToObject(TestData.MalformedToken, "ABC", verify: false); - - action.ShouldThrow(); - } - - [Fact] - public void DecodeToObject_Should_Throw_Exception_On_Invalid_Key() - { - Action action = () => JsonWebToken.DecodeToObject(TestData.Token, "XYZ", verify: true); - - action.ShouldThrow(); - } - - [Fact] - public void DecodeToObject_Should_Throw_Exception_On_Invalid_Expiration_Claim() - { - var invalidexptoken = JsonWebToken.Encode(new { exp = "asdsad" }, "ABC", JwtHashAlgorithm.HS256); - - Action action = () => JsonWebToken.DecodeToObject(invalidexptoken, "ABC", verify: true); - - action.ShouldThrow(); - } - - [Fact] - public void DecodeToObject_Should_Throw_Exception_On_Null_Expiration_Claim() - { - var invalidexptoken = JsonWebToken.Encode(new { exp = (object)null }, "ABC", JwtHashAlgorithm.HS256); - - Action action = () => JsonWebToken.DecodeToObject(invalidexptoken, "ABC", verify: true); - - action.ShouldThrow().WithMessage("Claim 'exp' must be a number."); - } - - [Fact] - public void DecodeToObject_Should_Throw_Exception_On_Expired_Claim() - { - var hourAgo = DateTime.UtcNow.Subtract(new TimeSpan(1, 0, 0)); - var unixTimestamp = (hourAgo - new DateTime(1970, 1, 1)).TotalSeconds; - var expiredtoken = JsonWebToken.Encode(new { exp = unixTimestamp }, "ABC", JwtHashAlgorithm.HS256); - - Action action = () => JsonWebToken.DecodeToObject(expiredtoken, "ABC", verify: true); - - action.ShouldThrow(); - } - - [Fact] - public void DecodeToObject_Should_DecodeToken_On_Exp_Claim_After_Year2038() - { - var serializer = new JsonNetSerializer(); - JsonWebToken.JsonSerializer = serializer; - - //Why 2038? https://en.wikipedia.org/wiki/Year_2038_problem - var post2038 = new DateTime(2038, 1, 19, 3, 14, 8, DateTimeKind.Utc); - var unixTimestamp = (post2038 - new DateTime(1970, 1, 1)).TotalSeconds; - var payload = new { exp = unixTimestamp }; - var validToken = JsonWebToken.Encode(payload, "ABC", JwtHashAlgorithm.HS256); - - var expectedPayload = serializer.Serialize(payload); - var actualPayload = JsonWebToken.Decode(validToken, "ABC", true); - - actualPayload.Should().Be(expectedPayload); - } - - [Fact] - public void DecodeToObject_Should_Throw_Exception_Before_NotBefore_Becomes_Valid() - { - var post2038 = new DateTime(2038, 1, 19, 3, 14, 8, DateTimeKind.Utc); - var nbf = (post2038 - JwtValidator.UnixEpoch).TotalSeconds; - var invalidnbftoken = JsonWebToken.Encode(new { nbf = nbf }, "ABC", JwtHashAlgorithm.HS256); - - Action action = () => JsonWebToken.DecodeToObject(invalidnbftoken, "ABC", verify: true); - - action.ShouldThrow().WithMessage("Token is not yet valid."); - } - - [Fact] - public void DecodeToObject_Should_Throw_Exception_On_Null_NotBefore_Claim() - { - var invalidnbftoken = JsonWebToken.Encode(new { nbf = (object)null }, "ABC", JwtHashAlgorithm.HS256); - - Action action = () => JsonWebToken.DecodeToObject(invalidnbftoken, "ABC", verify: true); - - action.ShouldThrow().WithMessage("Claim 'nbf' must be a number."); - } - - [Fact] - public void DecodeToObject_Should_Decode_Token_After_NotBefore_Becomes_Valid() - { - var nbf = (int)(DateTime.UtcNow - JwtValidator.UnixEpoch).TotalSeconds; - var validnbftoken = JsonWebToken.Encode(new { nbf = nbf }, "ABC", JwtHashAlgorithm.HS256); - - JsonWebToken.DecodeToObject(validnbftoken, "ABC", verify: true); - } - } -} \ No newline at end of file diff --git a/tests/JWT.Tests.Core/EncodeTests.cs b/tests/JWT.Tests.Core/EncodeTests.cs deleted file mode 100644 index 1f685182f..000000000 --- a/tests/JWT.Tests.Core/EncodeTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; -using FluentAssertions; -using JWT.Serializers; -using Xunit; -using JWT.Tests.Common; - -namespace JWT.Tests -{ - public class EncodeTests - { - [Fact] - public void Should_Encode_Type_With_JsonNet_Serializer() - { - JsonWebToken.JsonSerializer = new JsonNetSerializer(); - - var actual = JsonWebToken.Encode(TestData.Customer, "ABC", JwtHashAlgorithm.HS256); - - actual.Should().Be(TestData.Token); - } - - [Fact] - public void Should_Encode_Type_With_JsonNet_Serializer_And_Extra_Headers() - { - JsonWebToken.JsonSerializer = new JsonNetSerializer(); - - var extraheaders = new Dictionary { { "foo", "bar" } }; - var actual = JsonWebToken.Encode(extraheaders, TestData.Customer, "ABC", JwtHashAlgorithm.HS256); - - actual.Should().Be(TestData.ExtraHeadersToken); - } - } -} \ No newline at end of file diff --git a/tests/JWT.Tests.NETFramework/DecodeTests.cs b/tests/JWT.Tests.NETFramework/DecodeTests.cs deleted file mode 100644 index 879ce9aae..000000000 --- a/tests/JWT.Tests.NETFramework/DecodeTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -using FluentAssertions; -using JWT.Tests.Common; -using JWT.Tests.NETFramework.Serializers; -using Xunit; - -namespace JWT.Tests.NETFramework -{ - public class DecodeTests - { - [Fact] - public void Decode_Should_Decode_Token_To_Json_Encoded_String_With_WebScript_Serializer() - { - var serializer = new WebScriptJsonSerializer(); - JsonWebToken.JsonSerializer = serializer; - - var expectedPayload = serializer.Serialize(TestData.Customer); - - var actualPayload = JsonWebToken.Decode(TestData.Token, "ABC", verify: false); - - actualPayload.Should().Be(expectedPayload); - } - - [Fact] - public void Decode_Should_Decode_Token_To_Json_Encoded_String_With_ServiceStack_Serializer() - { - var serializer = new ServiceStackJsonSerializer(); - JsonWebToken.JsonSerializer = serializer; - - var expectedPayload = serializer.Serialize(TestData.Customer); - - var actualPayload = JsonWebToken.Decode(TestData.Token, "ABC", verify: false); - - actualPayload.Should().Be(expectedPayload); - } - - [Fact] - public void DecodeToObject_Should_Decode_Token_To_Dictionary_With_WebScript_Serializer() - { - JsonWebToken.JsonSerializer = new WebScriptJsonSerializer(); - - var actualPayload = JsonWebToken.DecodeToObject(TestData.Token, "ABC", verify: false); - - actualPayload.ShouldBeEquivalentTo(TestData.DictionaryPayload, options => options.IncludingAllRuntimeProperties()); - } - - [Fact] - public void DecodeToObject_Should_Decode_Token_To_Dictionary_With_ServiceStack_Serializer() - { - JsonWebToken.JsonSerializer = new ServiceStackJsonSerializer(); - - var actualPayload = JsonWebToken.DecodeToObject(TestData.Token, "ABC", verify: false); - - actualPayload.ShouldBeEquivalentTo(TestData.DictionaryPayload, options => options.IncludingAllRuntimeProperties()); - } - - [Fact] - public void DecodeToObject_Should_Decode_Token_To_Generic_Type_With_WebScript_Serializer() - { - JsonWebToken.JsonSerializer = new WebScriptJsonSerializer(); - - var actualPayload = JsonWebToken.DecodeToObject(TestData.Token, "ABC", verify: false); - - actualPayload.ShouldBeEquivalentTo(TestData.Customer); - } - - [Fact] - public void DecodeToObject_Should_Decode_Token_To_Generic_Type_With_ServiceStack_Serializer() - { - JsonWebToken.JsonSerializer = new ServiceStackJsonSerializer(); - - var actualPayload = JsonWebToken.DecodeToObject(TestData.Token, "ABC", verify: false); - - actualPayload.ShouldBeEquivalentTo(TestData.Customer); - } - - - } -} diff --git a/tests/JWT.Tests.NETFramework/EncodeTests.cs b/tests/JWT.Tests.NETFramework/EncodeTests.cs deleted file mode 100644 index 49e757f9e..000000000 --- a/tests/JWT.Tests.NETFramework/EncodeTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using FluentAssertions; -using JWT.Tests.Common; -using JWT.Tests.NETFramework.Serializers; -using System.Collections.Generic; -using Xunit; - -namespace JWT.Tests.NETFramework -{ - public class EncodeTests - { - [Fact] - public void Should_Encode_Type_With_WebScript_Serializer() - { - JsonWebToken.JsonSerializer = new WebScriptJsonSerializer(); - - var actual = JsonWebToken.Encode(TestData.Customer, "ABC", JwtHashAlgorithm.HS256); - - actual.Should().Be(TestData.Token); - } - - [Fact] - public void Should_Encode_Type_With_WebScript_Serializer_And_Extra_Headers() - { - JsonWebToken.JsonSerializer = new WebScriptJsonSerializer(); - - var extraheaders = new Dictionary { { "foo", "bar" } }; - var actual = JsonWebToken.Encode(extraheaders, TestData.Customer, "ABC", JwtHashAlgorithm.HS256); - - actual.Should().Be(TestData.ExtraHeadersToken); - } - - [Fact] - public void Should_Encode_Type_With_ServiceStack_Serializer() - { - JsonWebToken.JsonSerializer = new ServiceStackJsonSerializer(); - - var actual = JsonWebToken.Encode(TestData.Customer, "ABC", JwtHashAlgorithm.HS256); - - actual.Should().Be(TestData.Token); - } - - [Fact] - public void Should_Encode_Type_With_ServiceStack_Serializer_And_Extra_Headers() - { - JsonWebToken.JsonSerializer = new ServiceStackJsonSerializer(); - - var extraheaders = new Dictionary { { "foo", "bar" } }; - var actual = JsonWebToken.Encode(extraheaders, TestData.Customer, "ABC", JwtHashAlgorithm.HS256); - - actual.Should().Be(TestData.ExtraHeadersToken); - } - - } -} diff --git a/tests/JWT.Tests.NETFramework/JWT.Tests.NETFramework.csproj b/tests/JWT.Tests.NETFramework/JWT.Tests.NETFramework.csproj index c4950d67d..7560732bd 100644 --- a/tests/JWT.Tests.NETFramework/JWT.Tests.NETFramework.csproj +++ b/tests/JWT.Tests.NETFramework/JWT.Tests.NETFramework.csproj @@ -1,4 +1,4 @@ - + Debug @@ -66,8 +66,6 @@ - -