Add core support for AzureKeyVault.

This commit is contained in:
James Stumme 2017-02-24 17:23:31 -06:00
Родитель 5ce342035c
Коммит 9c035c9400
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: AAA261CFA10A3FC6
3 изменённых файлов: 86 добавлений и 2 удалений

Просмотреть файл

@ -70,7 +70,7 @@ namespace Microsoft.Extensions.Configuration
return result.AccessToken;
}
#if NET451
/// <summary>
/// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from the Azure KeyVault.
/// </summary>
@ -121,10 +121,13 @@ namespace Microsoft.Extensions.Configuration
private static async Task<string> GetTokenFromClientCertificate(string authority, string resource, string clientId, X509Certificate2 certificate)
{
var authContext = new AuthenticationContext(authority);
#if NET451
var result = await authContext.AcquireTokenAsync(resource, new ClientAssertionCertificate(clientId, certificate));
#else
var result = await authContext.AcquireTokenAsync(resource, new ClientAssertionCertificateCore(clientId, certificate));
#endif
return result.AccessToken;
}
#endif
/// <summary>
/// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from the Azure KeyVault.

Просмотреть файл

@ -0,0 +1,80 @@
using System;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.IdentityModel.Tokens;
namespace Microsoft.Extensions.Configuration.AzureKeyVault
{
/// <summary>
/// Containing certificate used to create client assertion.
/// </summary>
public sealed class ClientAssertionCertificateCore : IClientAssertionCertificate
{
/// <summary>
/// Constructor to create credential with client Id and certificate.
/// </summary>
/// <param name="clientId">Identifier of the client requesting the token.</param>
/// <param name="certificate">The certificate used as credential.</param>
public ClientAssertionCertificateCore(string clientId, X509Certificate2 certificate)
{
if (string.IsNullOrWhiteSpace(clientId))
{
throw new ArgumentNullException(nameof(clientId));
}
if (certificate == null)
{
throw new ArgumentNullException(nameof(certificate));
}
var key = new X509SecurityKey(certificate);
if (key.PublicKey.KeySize < MinKeySizeInBits)
{
throw new ArgumentOutOfRangeException(nameof(certificate),
$"The certificate used must have a key size of at least {MinKeySizeInBits} bits");
}
ClientId = clientId;
Certificate = certificate;
Key = key;
}
/// <summary>
/// Gets the identifier of the client requesting the token.
/// </summary>
public string ClientId { get; }
/// <summary>
/// Gets minimum X509 certificate key size in bits
/// </summary>
public static int MinKeySizeInBits => 2048;
/// <summary>
/// Gets the certificate used as credential.
/// </summary>
public X509Certificate2 Certificate { get; }
/// <summary>
/// Gets the security key from the credential.
/// </summary>
public X509SecurityKey Key { get; }
/// <summary>
/// Signs a message using the private key in the certificate
/// </summary>
/// <param name="message">Message that needs to be signed</param>
/// <returns>Signed message as a byte array</returns>
public byte[] Sign(string message)
{
using (var rsa = Key.CryptoProviderFactory.CreateForSigning(Key, SecurityAlgorithms.RsaSha256Signature))
return rsa.Sign(Encoding.UTF8.GetBytes(message));
}
/// <summary>
/// Returns thumbprint of the certificate
/// </summary>
public string Thumbprint => Base64UrlEncoder.Encode(Certificate.GetCertHash());
}
}

Просмотреть файл

@ -13,6 +13,7 @@
<ProjectReference Include="..\Microsoft.Extensions.Configuration\Microsoft.Extensions.Configuration.csproj" />
<ProjectReference Include="..\Microsoft.Extensions.Configuration.FileExtensions\Microsoft.Extensions.Configuration.FileExtensions.csproj" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.13.5" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.1.2" />
<PackageReference Include="Microsoft.Azure.KeyVault" Version="2.0.6" />
</ItemGroup>