azure-activedirectory-identitymodel-extensions-for-dotnet
azure-activedirectory-identitymodel-extensions-for-dotnet copied to clipboard
[Feature Request] Changing the kid header for a JWT
Is your feature request related to a problem? Please describe.
When using Azure Key Vault to sign a token, the kid value in the header is set with the key identifier for the Azure Key Vault key. Any tokens that are signed therefore expose the location of the keys/secrets, and for the kid header value to be unique, it forces us to point to a specific version of the key rather than relying on the latest.
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var callback = new KeyVaultSecurityKey.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback);
var certificateKeyId = "https://my-key-vault-instance.vault.azure.net/keys/certificate-name";
var tokenHandler = new JwtSecurityTokenHandler();
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(),
Issuer = _apiOptions.Value.Authority,
Expires = DateTime.UtcNow.AddHours(24),
IssuedAt = DateTime.UtcNow,
SigningCredentials = new SigningCredentials(new KeyVaultSecurityKey(certificateKeyId, callback), SecurityAlgorithms.RsaSha256)
{
CryptoProviderFactory = new CryptoProviderFactory { CustomCryptoProvider = new KeyVaultCryptoProvider() }
}
};
var jwt = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(jwt);
{
"alg": "RS256",
"kid": "https://my-key-vault-instance.vault.azure.net/keys/certificate-name",
"typ": "JWT"
}
Describe the solution you'd like
The kid value would be set to either the certificate thumbprint or the version string when creating a new token.
Describe alternatives you've considered
Being able to set the kid value in the token descriptor would be a workable alternative.
var tokenDescriptor = new SecurityTokenDescriptor
{
AdditionalHeaderClaims = new Dictionary<string, object>
{
{ "kid", customKidHeaderValue }
}
}
var tokenDescriptor = new SecurityTokenDescriptor
{
KeyId = customKidHeaderValue
}
As of now, I've been able to create workaround using reflection. This is done by creating a new type and overriding the KeyId property of KeyVaultSecurityKey, returning a different value if the calling type is JwtHeader.
@drmathias you bring up a good point, if you could specify easily the 'kid' to use, would that work?
Yes, that solution seems alright
Is there any suggested workaround for this? Other than reflection or creating our own implementation of KeyVaultSecurityKey