Jwt.Net, a JWT (JSON Web Token) implementation for .NET
This library supports generating and decoding JSON Web Tokens.
Installation
Package is avaliable via NuGet. Or you can download and compile it yourself.
Supported .NET Framework versions:
- .NET 4.6.0
- .NET Standard 1.3
Usage
Creating (encoding) token
var payload = new Dictionary<string, object>
{
{ "claim1", 0 },
{ "claim2", "claim2-value" }
};
const string secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
var token = encoder.Encode(payload, secret);
Console.WriteLine(token);Or using the fluent builder API
var token = new JwtBuilder()
.WithAlgorithm(new HMACSHA256Algorithm())
.WithSecret(secret)
.AddClaim("exp", DateTimeOffset.UtcNow.AddHours(1).ToUnixTimeSeconds())
.AddClaim("claim2", "claim2-value")
.Build();
Console.WriteLine(token);The output would be:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjbGFpbTEiOjAsImNsYWltMiI6ImNsYWltMi12YWx1ZSJ9.8pwBI_HtXqI3UgQHQ_rDRnSQRxFL1SR8fbQoS-5kM5s
Parsing (decoding) and verifying token
const string token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjbGFpbTEiOjAsImNsYWltMiI6ImNsYWltMi12YWx1ZSJ9.8pwBI_HtXqI3UgQHQ_rDRnSQRxFL1SR8fbQoS-5kM5s";
const string secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";
try
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
var json = decoder.Decode(token, secret, verify: true);
Console.WriteLine(json);
}
catch (TokenExpiredException)
{
Console.WriteLine("Token has expired");
}
catch (SignatureVerificationException)
{
Console.WriteLine("Token has invalid signature");
}Or using the fluent builder API
try
{
var json = new JwtBuilder()
.WithSecret(secret)
.MustVerifySignature()
.Decode(token);
Console.WriteLine(json);
}
catch (TokenExpiredException)
{
Console.WriteLine("Token has expired");
}
catch (SignatureVerificationException)
{
Console.WriteLine("Token has invalid signature");
}The output would be:
{ "claim1": 0, "claim2": "claim2-value" }
You can also deserialize the JSON payload directly to a .NET type:
var payload = decoder.DecodeToObject<IDictionary<string, object>>(token, secret);
Console.WriteLine(payload["claim2"]);Or using the fluent builder API
var payload = new JwtBuilder()
.WithSecret(secret)
.MustVerifySignature()
.Decode<IDictionary<string, object>>(token);
Console.WriteLine(payload["claim2"]);The output would be:
claim2-value
Set and validate token expiration
As described in the JWT RFC, the exp "claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing." If an exp claim is present and is prior to the current time the token will fail verification. The exp (expiry) value must be specified as the number of seconds since 1/1/1970 UTC.
IDateTimeProvider provider = new UtcDateTimeProvider();
var now = provider.GetNow();
var unixEpoch = JwtValidator.UnixEpoch; // 1970-01-01 00:00:00 UTC
var secondsSinceEpoch = Math.Round((now - unixEpoch).TotalSeconds);
var payload = new Dictionary<string, object>
{
{ "exp", secondsSinceEpoch }
};
cosnt string secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";
var token = encoder.Encode(payload, secret);
var json = decoder.Decode(token, secret); // throws TokenExpiredExceptionCustom JSON serializer
By default JSON serialization is performed by JsonNetSerializer implemented using Json.Net. To use a different one, implement the IJsonSerializer interface:
public class CustomJsonSerializer : IJsonSerializer
{
public string Serialize(object obj)
{
// Implement using favorite JSON serializer
}
public T Deserialize<T>(string json)
{
// Implement using favorite JSON serializer
}
}And then pass this serializer as a dependency to JwtEncoder constructor:
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new CustomJsonSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);Custom JSON serialization settings with the default JsonNetSerializer
As mentioned above, the default JSON serialization is done by JsonNetSerializer. You can define your own custom serialization settings as follows:
JsonSerializer customJsonSerializer = new JsonSerializer
{
// All json keys start with lowercase characters instead of the exact casing of the model/property, e.g. fullName
ContractResolver = new CamelCasePropertyNamesContractResolver(),
// Nice and easy to read, but you can also use Formatting.None to reduce the payload size
Formatting = Formatting.Indented,
// The most appropriate datetime format.
DateFormatHandling = DateFormatHandling.IsoDateFormat,
// Don't add keys/values when the value is null.
NullValueHandling = NullValueHandling.Ignore,
// Use the enum string value, not the implicit int value, e.g. "red" for enum Color { Red }
Converters.Add(new StringEnumConverter())
};
IJsonSerializer serializer = new JsonNetSerializer(customJsonSerializer);
Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
