JSON Web Token
Code samples
Create JWT Client Assertion with X509 certificate signature (C#)
public static class JsonWebTokenHandler
{
/// <summary>
/// Creates a JWT client assertion used for authenticating an OAuth client.
/// </summary>
/// <param name="certificate">Certificate that includes both public and private key.</param>
/// <param name="clientId">Your OAuth client id, this can be found here: https://beta.oauth.vlaanderen.be/admin/OAuthClients.</param>
/// <param name="endpoint">e.g. https://beta.oauth.vlaanderen.be/authorization/ws/oauth/v2/token</param>
/// <returns>JWT client assertion</returns>
public static string CreateJwtClientAssertion(X509Certificate2 certificate, string clientId, string endpoint)
{
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Expires = DateTime.UtcNow.AddMinutes(960),
SigningCredentials = new SigningCredentials(new X509SecurityKey(certificate), SecurityAlgorithms.RsaSha256Signature),
Subject = new ClaimsIdentity(new List<Claim>
{
new Claim("sub", clientId),
new Claim("iss", clientId),
new Claim("jti", Guid.NewGuid().ToString()),
new Claim("aud", endpoint)
})
};
return tokenHandler.WriteToken(tokenHandler.CreateJwtSecurityToken(tokenDescriptor));
}
}
Create JWT Client Assertion with key pair signature (C#)
Generate key pair
using System;
using System.IO;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace GenerateJsonWebKey
{
class Program
{
const string privateKeyFileName = "jsonwebkeyprivate.key";
const string publicKeyFileName = "jsonwebkeypublic.key";
public static async Task Main()
{
var parametersPublic = default(RSAParameters);
var parametersPrivate = default(RSAParameters);
Console.WriteLine("Generating RSA key...");
using (var rsa = new RSACryptoServiceProvider(2048))
{
parametersPrivate = rsa.ExportParameters(true);
parametersPublic = rsa.ExportParameters(false);
}
var keyId = $"{Guid.NewGuid()}";
var key = new Microsoft.Azure.KeyVault.WebKey.JsonWebKey(parametersPrivate);
var keyPublic = new Microsoft.Azure.KeyVault.WebKey.JsonWebKey(parametersPublic);
key.Kid = keyId;
keyPublic.Kid = keyId;
var jsonPrivate = JObject.Parse(key.ToString());
jsonPrivate.Add("use", "sig");
jsonPrivate.Add("alg", "RS512");
var jsonPublic = JObject.Parse(keyPublic.ToString());
jsonPublic.Add("use", "sig");
jsonPublic.Add("alg", "RS512");
Console.WriteLine("Public Key");
Console.WriteLine(jsonPublic.ToString());
Console.WriteLine(Environment.NewLine);
Console.WriteLine("Private key");
Console.WriteLine(jsonPrivate.ToString());
Console.WriteLine(Environment.NewLine);
Console.WriteLine($"Writing public key to file {publicKeyFileName}.");
await File.WriteAllTextAsync(publicKeyFileName, jsonPublic.ToString());
Console.WriteLine(Environment.NewLine);
Console.WriteLine($"Writing private key to file {privateKeyFileName}.");
await File.WriteAllTextAsync(privateKeyFileName, jsonPrivate.ToString());
Console.Read();
}
}
}
Create JWT Client Assertion based on the generated key pair
public class OAuthOptions
{
public int ClientId { get; set; }
public List<string> Scopes { get; set; }
public Uri TokenEndpoint { get; set; }
public string JsonWebKey { get; set; }
}
//...
private string CreateJwtClientAssertion(OAuthOptions oAuthOptions, Microsoft.IdentityModel.Tokens.JsonWebKey jwk)
{
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Expires = DateTime.UtcNow.AddMinutes(960),
SigningCredentials = new SigningCredentials(jwk, SecurityAlgorithms.RsaSha512Signature),
Subject = new ClaimsIdentity(new List<Claim>
{
new Claim("sub", oAuthOptions.ClientId.ToString()),
new Claim("iss", oAuthOptions.ClientId.ToString()),
new Claim("jti", Guid.NewGuid().ToString()),
new Claim("aud", oAuthOptions.TokenEndpoint.ToString())
)
};
return tokenHandler.WriteToken(tokenHandler.CreateJwtSecurityToken(tokenDescriptor));
}