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

Port to .NET Standard #72

Merged
merged 11 commits into from
Apr 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 0 additions & 18 deletions JWT.nuspec

This file was deleted.

42 changes: 26 additions & 16 deletions JWT.sln
Original file line number Diff line number Diff line change
@@ -1,35 +1,45 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio 15
VisualStudioVersion = 15.0.26228.9
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JWT", "src\JWT\JWT.csproj", "{A80B51B8-DDF6-4026-98A4-B59653E50B38}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JWT.Tests", "tests\JWT.Tests\JWT.Tests.csproj", "{BF568781-D576-4545-A552-4DC839B1AF14}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{513CE2B5-E0D6-43BC-998A-A02CB2875479}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitignore = .gitignore
JWT.nuspec = JWT.nuspec
package.cmd = package.cmd
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JWT", "src\JWT\JWT.csproj", "{2F79EB8D-5B33-4EA6-AC1A-89B107F043D2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JWT.Tests.Core", "tests\JWT.Tests.Core\JWT.Tests.Core.csproj", "{79341F14-151C-4231-B2A7-56DAC44CB25E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JWT.Tests.NETFramework", "tests\JWT.Tests.NETFramework\JWT.Tests.NETFramework.csproj", "{88E1DB97-3507-4D8C-9B3D-715DE2F9E414}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JWT.Tests.Common", "tests\JWT.Tests.Common\JWT.Tests.Common.csproj", "{5D0282D5-9CC4-4D42-A3F0-E18270F92184}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A80B51B8-DDF6-4026-98A4-B59653E50B38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A80B51B8-DDF6-4026-98A4-B59653E50B38}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A80B51B8-DDF6-4026-98A4-B59653E50B38}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A80B51B8-DDF6-4026-98A4-B59653E50B38}.Release|Any CPU.Build.0 = Release|Any CPU
{BF568781-D576-4545-A552-4DC839B1AF14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF568781-D576-4545-A552-4DC839B1AF14}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF568781-D576-4545-A552-4DC839B1AF14}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF568781-D576-4545-A552-4DC839B1AF14}.Release|Any CPU.Build.0 = Release|Any CPU
{2F79EB8D-5B33-4EA6-AC1A-89B107F043D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F79EB8D-5B33-4EA6-AC1A-89B107F043D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F79EB8D-5B33-4EA6-AC1A-89B107F043D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F79EB8D-5B33-4EA6-AC1A-89B107F043D2}.Release|Any CPU.Build.0 = Release|Any CPU
{79341F14-151C-4231-B2A7-56DAC44CB25E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79341F14-151C-4231-B2A7-56DAC44CB25E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79341F14-151C-4231-B2A7-56DAC44CB25E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79341F14-151C-4231-B2A7-56DAC44CB25E}.Release|Any CPU.Build.0 = Release|Any CPU
{88E1DB97-3507-4D8C-9B3D-715DE2F9E414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88E1DB97-3507-4D8C-9B3D-715DE2F9E414}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88E1DB97-3507-4D8C-9B3D-715DE2F9E414}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88E1DB97-3507-4D8C-9B3D-715DE2F9E414}.Release|Any CPU.Build.0 = Release|Any CPU
{5D0282D5-9CC4-4D42-A3F0-E18270F92184}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D0282D5-9CC4-4D42-A3F0-E18270F92184}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D0282D5-9CC4-4D42-A3F0-E18270F92184}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D0282D5-9CC4-4D42-A3F0-E18270F92184}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
11 changes: 0 additions & 11 deletions package.cmd

This file was deleted.

4 changes: 4 additions & 0 deletions src/JWT/Algorithms/RS256Algorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ public RS256Algorithm(X509Certificate2 cert)

public byte[] Sign(byte[] key, byte[] bytesToSign)
{
#if NETSTANDARD1_3
var rsa = (RSACryptoServiceProvider)_cert.GetRSAPrivateKey();
#else
var rsa = (RSACryptoServiceProvider)_cert.PrivateKey;
#endif
var param = new CspParameters
{
KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
Expand Down
98 changes: 32 additions & 66 deletions src/JWT/JWT.csproj
Original file line number Diff line number Diff line change
@@ -1,74 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A80B51B8-DDF6-4026-98A4-B59653E50B38}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>JWT</RootNamespace>
<AssemblyName>JWT</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<TargetFrameworks>net35;netstandard1.3</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<PropertyGroup Condition="'$(TargetFramework)' == 'net35'">
<TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
<DefineConstants>NET35</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<DefineConstants>NETSTANDARD1_3</DefineConstants>
</PropertyGroup>

<PropertyGroup>
<Company>Public Domain</Company>
<Copyright>Public Domain</Copyright>
<Description>JWT.NET, a JWT (JSON Web Token) implementation for .NET</Description>
<RepositoryUrl>https://github.com/jwt-dotnet/jwt</RepositoryUrl>
<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-beta1</Version>
<PackageTags>jwt json</PackageTags>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DocumentationFile>bin\Debug\netstandard1.3\JWT.xml</DocumentationFile>
<OutputPath>bin\Debug\netstandard1.3\</OutputPath>
</PropertyGroup>

<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.10.0.2\lib\net35\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="AlgorithmFactory.cs" />
<Compile Include="Algorithms\HMACSHA256Algorithm.cs" />
<Compile Include="Algorithms\HMACSHA384Algorithm.cs" />
<Compile Include="Algorithms\HMACSHA512Algorithm.cs" />
<Compile Include="Algorithms\RS256Algorithm.cs" />
<Compile Include="IBase64UrlEncoder.cs" />
<Compile Include="IDateTimeProvider.cs" />
<Compile Include="IJsonSerializer.cs" />
<Compile Include="IJwtAlgorithm.cs" />
<Compile Include="IJwtDecoder.cs" />
<Compile Include="IJwtEncoder.cs" />
<Compile Include="IJwtValidator.cs" />
<Compile Include="JsonWebToken.cs" />
<Compile Include="JwtBase64UrlEncoder.cs" />
<Compile Include="JwtDecoder.cs" />
<Compile Include="JwtEncoder.cs" />
<Compile Include="JwtHashAlgorithm.cs" />
<Compile Include="JwtValidator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Serializers\JsonNetSerializer.cs" />
<Compile Include="SignatureVerificationException.cs" />
<Compile Include="TokenExpiredException.cs" />
<Compile Include="UtcDateTimeProvider.cs" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
<PackageReference Include="System.Security.Cryptography.Csp" Version="4.3.0" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
18 changes: 0 additions & 18 deletions src/JWT/Properties/AssemblyInfo.cs

This file was deleted.

4 changes: 0 additions & 4 deletions src/JWT/packages.config

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace JWT.Tests
{
internal class Customer
{
public string FirstName { get; set; }
public int Age { get; set; }
}
namespace JWT.Tests.Common
{
public class Customer
{
public string FirstName { get; set; }

public int Age { get; set; }
}
}
7 changes: 7 additions & 0 deletions tests/JWT.Tests.Common/JWT.Tests.Common.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
</PropertyGroup>

</Project>
19 changes: 19 additions & 0 deletions tests/JWT.Tests.Common/TestData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Collections.Generic;

namespace JWT.Tests.Common
{
public static class TestData
{
public static readonly Customer Customer = new Customer { FirstName = "Bob", Age = 37 };

public const string Token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJGaXJzdE5hbWUiOiJCb2IiLCJBZ2UiOjM3fQ.cr0xw8c_HKzhFBMQrseSPGoJ0NPlRp_3BKzP96jwBdY";
public const string MalformedToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9eyJGaXJzdE5hbWUiOiJCb2IiLCJBZ2UiOjM3fQ.cr0xw8c_HKzhFBMQrseSPGoJ0NPlRp_3BKzP96jwBdY";
public const string ExtraHeadersToken = "eyJmb28iOiJiYXIiLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJGaXJzdE5hbWUiOiJCb2IiLCJBZ2UiOjM3fQ.slrbXF9VSrlX7LKsV-Umb_zEzWLxQjCfUOjNTbvyr1g";

public static readonly IDictionary<string, object> DictionaryPayload = new Dictionary<string, object>
{
{ "FirstName", "Bob" },
{ "Age", 37 }
};
}
}
101 changes: 101 additions & 0 deletions tests/JWT.Tests.Core/DecodeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
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<Customer>(TestData.Token, "ABC", verify: false);

actualPayload.ShouldBeEquivalentTo(TestData.Customer);
}

[Fact]
public void DecodeToObject_Should_Throw_Exception_On_MalformedToken()
{
Action action = () => JsonWebToken.DecodeToObject<Customer>(TestData.MalformedToken, "ABC", verify: false);

action.ShouldThrow<ArgumentException>();
}

[Fact]
public void DecodeToObject_Should_Throw_Exception_On_Invalid_Key()
{
Action action = () => JsonWebToken.DecodeToObject<Customer>(TestData.Token, "XYZ", verify: true);

action.ShouldThrow<SignatureVerificationException>();
}

[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<Customer>(invalidexptoken, "ABC", verify: true);

action.ShouldThrow<SignatureVerificationException>();
}

[Fact]
public void DecodeToObject_Should_Throw_Exception_On_Expired_Claim()
{
var hourAgo = DateTime.UtcNow.Subtract(new TimeSpan(1, 0, 0));
var unixTimestamp = (int)(hourAgo - new DateTime(1970, 1, 1)).TotalSeconds;
var expiredtoken = JsonWebToken.Encode(new { exp = unixTimestamp }, "ABC", JwtHashAlgorithm.HS256);

Action action = () => JsonWebToken.DecodeToObject<Customer>(expiredtoken, "ABC", verify: true);

action.ShouldThrow<TokenExpiredException>();
}

[Fact]
public void DecodeToObject_Should_Throw_Exception_Before_NotBefore_Becomes_Valid()
{
var nbf = (int)(DateTime.UtcNow.AddHours(1) - JwtValidator.UnixEpoch).TotalSeconds;
var invalidnbftoken = JsonWebToken.Encode(new { nbf = nbf }, "ABC", JwtHashAlgorithm.HS256);

Action action = () => JsonWebToken.DecodeToObject<Customer>(invalidnbftoken, "ABC", verify: true);

action.ShouldThrow<SignatureVerificationException>();
}

[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<Customer>(validnbftoken, "ABC", verify: true);
}
}
}
Loading