Removing KeyVault plugin from the repository. (#18)
This is a part of #17
This commit is contained in:
Родитель
731ad915f5
Коммит
95a8feca36
|
@ -5,12 +5,8 @@ VisualStudioVersion = 15.0.26430.15
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7D8B793C-F4AC-432A-8EE7-2EE3C2B16EC1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ServiceBus.KeyVaultPlugin", "src\Microsoft.Azure.ServiceBus.KeyVaultPlugin\Microsoft.Azure.ServiceBus.KeyVaultPlugin.csproj", "{F942A66E-A1B7-41C3-85E8-1A108D18F890}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{B18143EB-5FF4-4AFC-B086-709DC9B92546}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ServiceBus.KeyVault.Test", "test\Microsoft.Azure.ServiceBus.KeyVault.Test\Microsoft.Azure.ServiceBus.KeyVault.Test.csproj", "{DC8DC685-DCB5-47C7-A2B7-41D31EDDCAED}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ServiceBus.MessageIdPlugin", "src\Microsoft.Azure.ServiceBus.MessageIdPlugin\Microsoft.Azure.ServiceBus.MessageIdPlugin.csproj", "{7EAE339B-16CC-418C-BB17-070E10BE8283}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.ServiceBus.MessageId.Test", "test\Microsoft.Azure.ServiceBus.MessageId.Test\Microsoft.Azure.ServiceBus.MessageId.Test.csproj", "{F2FF1744-AE2B-440D-93AB-92C5B832FF25}"
|
||||
|
@ -28,14 +24,6 @@ Global
|
|||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F942A66E-A1B7-41C3-85E8-1A108D18F890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F942A66E-A1B7-41C3-85E8-1A108D18F890}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F942A66E-A1B7-41C3-85E8-1A108D18F890}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F942A66E-A1B7-41C3-85E8-1A108D18F890}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DC8DC685-DCB5-47C7-A2B7-41D31EDDCAED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DC8DC685-DCB5-47C7-A2B7-41D31EDDCAED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DC8DC685-DCB5-47C7-A2B7-41D31EDDCAED}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DC8DC685-DCB5-47C7-A2B7-41D31EDDCAED}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7EAE339B-16CC-418C-BB17-070E10BE8283}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7EAE339B-16CC-418C-BB17-070E10BE8283}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7EAE339B-16CC-418C-BB17-070E10BE8283}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -53,8 +41,6 @@ Global
|
|||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{F942A66E-A1B7-41C3-85E8-1A108D18F890} = {7D8B793C-F4AC-432A-8EE7-2EE3C2B16EC1}
|
||||
{DC8DC685-DCB5-47C7-A2B7-41D31EDDCAED} = {B18143EB-5FF4-4AFC-B086-709DC9B92546}
|
||||
{7EAE339B-16CC-418C-BB17-070E10BE8283} = {7D8B793C-F4AC-432A-8EE7-2EE3C2B16EC1}
|
||||
{F2FF1744-AE2B-440D-93AB-92C5B832FF25} = {B18143EB-5FF4-4AFC-B086-709DC9B92546}
|
||||
{63F75042-620C-4B08-BE41-D7EB64479A80} = {B18143EB-5FF4-4AFC-B086-709DC9B92546}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|Build/Package|Status|
|
||||
|------|-------------|
|
||||
|Microsoft.Azure.ServiceBus.MessageIdPlugin|[![NuGet Version and Downloads count](https://buildstats.info/nuget/Microsoft.Azure.ServiceBus.MessageIdPlugin?includePreReleases=true)](https://www.nuget.org/packages/Microsoft.Azure.ServiceBus.MessageIdPlugin/)|
|
||||
|Microsoft.Azure.ServiceBus.KeyVaultPlugin|[![NuGet Version and Downloads count](https://buildstats.info/nuget/Microsoft.Azure.ServiceBus.KeyVaultPlugin?includePreReleases=true)](https://www.nuget.org/packages/Microsoft.Azure.ServiceBus.KeyVaultPlugin/)|
|
||||
|
||||
This repository is for plugins for the [.NET Standard Azure Service Bus library](https://github.com/azure/azure-service-bus-dotnet) owned by the Azure-Service-Bus team.
|
||||
|
||||
|
@ -19,7 +18,6 @@ This library is built using .NET Standard 1.3. For more information on what plat
|
|||
|
||||
## Plugins included with this repository
|
||||
|
||||
* [Key Vault](./src/Microsoft.Azure.ServiceBus.KeyVaultPlugin/readme.md)
|
||||
* [Message ID](./src/Microsoft.Azure.ServiceBus.MessageIdPlugin/readme.md)
|
||||
|
||||
## Third party provided plugins
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.Plugins
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal interface ISecretManager
|
||||
{
|
||||
Task<byte[]> GetHashedSecret(string secretName, string secretVersion);
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.Plugins
|
||||
{
|
||||
internal static class KeyVaultMessageHeaders
|
||||
{
|
||||
internal const string InitializationVectorPropertyName = "KeyVault-IV";
|
||||
internal const string KeyNamePropertyName = "KeyVault-KeyName";
|
||||
internal const string KeyVersionPropertyName = "KeyVault-KeyVersion";
|
||||
}
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.Plugins
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.ServiceBus.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Provides Azure KeyVault functionality for Azure Service Bus.
|
||||
/// </summary>
|
||||
public class KeyVaultPlugin : ServiceBusPlugin
|
||||
{
|
||||
private readonly string secretName;
|
||||
private readonly string secretVersion;
|
||||
private ISecretManager secretManager;
|
||||
private byte[] initializationVector;
|
||||
private string base64InitializationVector;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name that is used to identify this plugin.
|
||||
/// </summary>
|
||||
public override string Name => "Microsoft.Azure.ServiceBus.KeyVault.KeyVaultPlugin";
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of an <see cref="KeyVaultPlugin"/>.
|
||||
/// </summary>
|
||||
/// <param name="encryptionSecretName">The name of the secret used to encrypt / decrypt messages.</param>
|
||||
/// <param name="keyVaultSettings">The <see cref="KeyVaultPluginSettings"/> used to create a new instance.</param>
|
||||
public KeyVaultPlugin(string encryptionSecretName, KeyVaultPluginSettings keyVaultSettings)
|
||||
: this(encryptionSecretName, string.Empty, keyVaultSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of an <see cref="KeyVaultPlugin"/>.
|
||||
/// </summary>
|
||||
/// <param name="encryptionSecretName">The name of the secret used to encrypt / decrypt messages.</param>
|
||||
/// <param name="encryptionSecretVersion">The version of the secret</param>
|
||||
/// <param name="keyVaultSettings">The <see cref="KeyVaultPluginSettings"/> used to create a new instance.</param>
|
||||
public KeyVaultPlugin(string encryptionSecretName, string encryptionSecretVersion, KeyVaultPluginSettings keyVaultSettings)
|
||||
{
|
||||
if (string.IsNullOrEmpty(encryptionSecretName))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(encryptionSecretName));
|
||||
}
|
||||
if (keyVaultSettings == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(keyVaultSettings));
|
||||
}
|
||||
|
||||
this.secretName = encryptionSecretName;
|
||||
this.secretVersion = encryptionSecretVersion;
|
||||
this.secretManager = new KeyVaultSecretManager(keyVaultSettings.Endpoint, keyVaultSettings.ClientId, keyVaultSettings.ClientSecret);
|
||||
this.initializationVector = KeyVaultPlugin.GenerateInitializationVector();
|
||||
this.base64InitializationVector = Convert.ToBase64String(this.initializationVector);
|
||||
}
|
||||
|
||||
internal KeyVaultPlugin(string encryptionSecretName, ISecretManager secretManager)
|
||||
{
|
||||
this.secretName = encryptionSecretName;
|
||||
this.secretManager = secretManager;
|
||||
this.initializationVector = KeyVaultPlugin.GenerateInitializationVector();
|
||||
this.base64InitializationVector = Convert.ToBase64String(this.initializationVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The action performed before sending a message to Service Bus. This method will load the KeyVault key and encrypt messages.
|
||||
/// </summary>
|
||||
/// <param name="message">The <see cref="Message"/> to be encrypted.</param>
|
||||
/// <returns>The encrypted <see cref="Message"/>.</returns>
|
||||
public override async Task<Message> BeforeMessageSend(Message message)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skip encryption if message properties are already set
|
||||
if (message.UserProperties.ContainsKey(KeyVaultMessageHeaders.InitializationVectorPropertyName)
|
||||
|| message.UserProperties.ContainsKey(KeyVaultMessageHeaders.KeyNamePropertyName)
|
||||
|| message.UserProperties.ContainsKey(KeyVaultMessageHeaders.KeyVersionPropertyName))
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
var secret = await secretManager.GetHashedSecret(secretName, secretVersion).ConfigureAwait(false);
|
||||
|
||||
message.UserProperties.Add(KeyVaultMessageHeaders.InitializationVectorPropertyName, base64InitializationVector);
|
||||
message.UserProperties.Add(KeyVaultMessageHeaders.KeyNamePropertyName, secretName);
|
||||
message.UserProperties.Add(KeyVaultMessageHeaders.KeyVersionPropertyName, secretVersion);
|
||||
|
||||
message.Body = await KeyVaultPlugin.Encrypt(message.Body, secret, this.initializationVector).ConfigureAwait(false);
|
||||
return message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new KeyVaultPluginException(Resources.BeforeMessageSendException, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The action performed after receiving a message from Service Bus. This method will load the KeyVault key and decrypt messages.
|
||||
/// </summary>
|
||||
/// <param name="message">The <see cref="Message"/> to be decrypted.</param>
|
||||
/// <returns>The decrypted <see cref="Message"/>.</returns>
|
||||
public override async Task<Message> AfterMessageReceive(Message message)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skip decryption we are missing properties for the key and IV.
|
||||
if (!message.UserProperties.ContainsKey(KeyVaultMessageHeaders.InitializationVectorPropertyName)
|
||||
|| !message.UserProperties.ContainsKey(KeyVaultMessageHeaders.KeyNamePropertyName))
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
var iVString = message.UserProperties[KeyVaultMessageHeaders.InitializationVectorPropertyName] as string;
|
||||
var iV = Convert.FromBase64String(iVString);
|
||||
var secretName = message.UserProperties[KeyVaultMessageHeaders.KeyNamePropertyName] as string;
|
||||
|
||||
// Remove properties before giving the message back
|
||||
message.UserProperties.Remove(KeyVaultMessageHeaders.InitializationVectorPropertyName);
|
||||
message.UserProperties.Remove(KeyVaultMessageHeaders.KeyNamePropertyName);
|
||||
|
||||
string secretVersion = string.Empty;
|
||||
if (message.UserProperties.ContainsKey(KeyVaultMessageHeaders.KeyVersionPropertyName))
|
||||
{
|
||||
secretVersion = message.UserProperties[KeyVaultMessageHeaders.KeyVersionPropertyName] as string;
|
||||
message.UserProperties.Remove(KeyVaultMessageHeaders.KeyVersionPropertyName);
|
||||
}
|
||||
|
||||
var secret = await secretManager.GetHashedSecret(secretName, secretVersion).ConfigureAwait(false);
|
||||
|
||||
var decryptedMessage = await KeyVaultPlugin.Decrypt(message.Body, secret, iV).ConfigureAwait(false);
|
||||
|
||||
message.Body = decryptedMessage;
|
||||
return message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new KeyVaultPluginException(Resources.AfterMessageReceiveException, ex);
|
||||
}
|
||||
}
|
||||
|
||||
internal static byte[] GenerateInitializationVector()
|
||||
{
|
||||
byte[] initializationVector = null;
|
||||
using (var aes = Aes.Create())
|
||||
{
|
||||
aes.GenerateIV();
|
||||
initializationVector = aes.IV;
|
||||
}
|
||||
return initializationVector;
|
||||
}
|
||||
|
||||
// Taken from the examples here: https://msdn.microsoft.com/en-us/library/system.security.cryptography.aes
|
||||
internal static async Task<byte[]> Encrypt(byte[] payload, byte[] key, byte[] initializationVector)
|
||||
{
|
||||
// Create an Aes object
|
||||
// with the specified key and IV.
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = key;
|
||||
aesAlg.IV = initializationVector;
|
||||
|
||||
var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
return await PerformCryptography(encryptor, payload).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Taken from the examples here: https://msdn.microsoft.com/en-us/library/system.security.cryptography.aes
|
||||
internal static async Task<byte[]> Decrypt(byte[] payload, byte[] key, byte[] initializationVector)
|
||||
{
|
||||
// Create an Aes object
|
||||
// with the specified key and IV.
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = key;
|
||||
aesAlg.IV = initializationVector;
|
||||
|
||||
var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
|
||||
|
||||
return await PerformCryptography(decryptor, payload).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<byte[]> PerformCryptography(ICryptoTransform cryptoTransform, byte[] data)
|
||||
{
|
||||
// Create the streams used for encryption.
|
||||
using (var memoryStream = new MemoryStream())
|
||||
using (var cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
|
||||
{
|
||||
// Write all data to the memory stream.
|
||||
await cryptoStream.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.Plugins
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Represents errors that occur within the <see cref="KeyVaultPlugin"/>.
|
||||
/// </summary>
|
||||
public class KeyVaultPluginException : Exception
|
||||
{
|
||||
internal KeyVaultPluginException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.Plugins
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The endpoint settings used to create a new <see cref="KeyVaultPlugin"/>.
|
||||
/// </summary>
|
||||
public class KeyVaultPluginSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="KeyVaultPluginSettings"/> object and validates the settings.
|
||||
/// </summary>
|
||||
/// <param name="clientId">The endpoint should be a guid.</param>
|
||||
/// <param name="endpoint">The endpoint should resemble: https://{keyvault-name}.vault.azure.net/</param>
|
||||
/// <param name="clientSecret">The secret should be a token.</param>
|
||||
public KeyVaultPluginSettings(string clientId, string endpoint, string clientSecret)
|
||||
{
|
||||
if (string.IsNullOrEmpty(clientId))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(clientId));
|
||||
}
|
||||
if (string.IsNullOrEmpty(endpoint))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(endpoint));
|
||||
}
|
||||
if (string.IsNullOrEmpty(clientSecret))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(clientSecret));
|
||||
}
|
||||
|
||||
this.ClientId = clientId;
|
||||
this.Endpoint = endpoint;
|
||||
this.ClientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeyVault endpoint.
|
||||
/// </summary>
|
||||
public string Endpoint { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeyVault ClientId.
|
||||
/// </summary>
|
||||
public string ClientId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the KeyVaultClientSecret.
|
||||
/// </summary>
|
||||
public string ClientSecret { get; }
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.Plugins
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.KeyVault;
|
||||
using Microsoft.Azure.KeyVault.Models;
|
||||
using Microsoft.IdentityModel.Clients.ActiveDirectory;
|
||||
|
||||
internal class KeyVaultSecretManager : ISecretManager
|
||||
{
|
||||
private static ConcurrentDictionary<string, byte[]> secretCache;
|
||||
private string azureClientId;
|
||||
private string azureClientSecret;
|
||||
|
||||
internal string KeyVaultUrl { get; private set; }
|
||||
|
||||
internal KeyVaultSecretManager(string keyVaultUrl, string azureClientId, string azureClientSecret)
|
||||
{
|
||||
if (string.IsNullOrEmpty(keyVaultUrl))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(keyVaultUrl));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(azureClientId))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(azureClientId));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(azureClientSecret))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(azureClientSecret));
|
||||
}
|
||||
|
||||
secretCache = new ConcurrentDictionary<string, byte[]>();
|
||||
this.KeyVaultUrl = keyVaultUrl;
|
||||
this.azureClientId = azureClientId;
|
||||
this.azureClientSecret = azureClientSecret;
|
||||
}
|
||||
|
||||
public async Task<byte[]> GetHashedSecret(string secretName, string secretVersion)
|
||||
{
|
||||
var combinedNameAndVersion = FormatSecretNameAndVersion(secretName, secretVersion);
|
||||
if (secretCache.ContainsKey(combinedNameAndVersion))
|
||||
{
|
||||
return secretCache[combinedNameAndVersion];
|
||||
}
|
||||
|
||||
var secret = await GetSecretFromKeyVault(secretName, secretVersion).ConfigureAwait(false);
|
||||
using (var sha256 = SHA256.Create())
|
||||
{
|
||||
var secretAsBytes = Encoding.UTF8.GetBytes(secret);
|
||||
var hashedSecret = sha256.ComputeHash(secretAsBytes);
|
||||
secretCache.GetOrAdd(combinedNameAndVersion, hashedSecret);
|
||||
return hashedSecret;
|
||||
}
|
||||
}
|
||||
|
||||
internal string FormatSecretNameAndVersion(string secretName, string secretVersion)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(secretVersion))
|
||||
{
|
||||
return secretName;
|
||||
}
|
||||
return string.Concat(secretName, "_", secretVersion);
|
||||
}
|
||||
|
||||
private async Task<string> GetSecretFromKeyVault(string secretName, string secretVersion)
|
||||
{
|
||||
using (var keyVaultClient = new KeyVaultClient(GetAccessToken))
|
||||
{
|
||||
try
|
||||
{
|
||||
SecretBundle secretResult;
|
||||
if (string.IsNullOrWhiteSpace(secretVersion))
|
||||
{
|
||||
secretResult = await keyVaultClient.GetSecretAsync(this.KeyVaultUrl, secretName).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
secretResult = await keyVaultClient.GetSecretAsync(this.KeyVaultUrl, secretName, secretVersion).ConfigureAwait(false);
|
||||
}
|
||||
return secretResult.Value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new KeyVaultPluginException(string.Format(Resources.KeyVaultKeyAcquisitionFailure, secretName, secretVersion, KeyVaultUrl), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetAccessToken(string authority, string resource, string scope)
|
||||
{
|
||||
var credential = new ClientCredential(this.azureClientId, this.azureClientSecret);
|
||||
var ctx = new AuthenticationContext(new Uri(authority).AbsoluteUri, false);
|
||||
|
||||
try
|
||||
{
|
||||
var result = await ctx.AcquireTokenAsync(resource, credential).ConfigureAwait(false);
|
||||
return result.AccessToken;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new KeyVaultPluginException(string.Format(Resources.AzureAdTokenAcquisitionFailure, KeyVaultUrl), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Microsoft.Azure.ServiceBus KeyVault extension</Description>
|
||||
<AssemblyTitle>Microsoft.Azure.ServiceBus.KeyVault</AssemblyTitle>
|
||||
<VersionPrefix>0.0.1-preview</VersionPrefix>
|
||||
<Authors>Microsoft</Authors>
|
||||
<TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<AssemblyName>Microsoft.Azure.ServiceBus.KeyVaultPlugin</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>../../build/keyfile.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
<PackageId>Microsoft.Azure.ServiceBus.KeyVaultPlugin</PackageId>
|
||||
<PackageTags>Azure;Service Bus;ServiceBus;.NET;AMQP;IoT;Queue;Topic;KeyVault;Encryption;Plugin</PackageTags>
|
||||
<PackageReleaseNotes>https://github.com/Azure/azure-service-bus-dotnet-plugins/releases</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/Azure/azure-service-bus-dotnet-plugins/master/service-bus.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/Azure/azure-service-bus-dotnet-plugins</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://raw.githubusercontent.com/Azure/azure-service-bus-dotnet-plugins/master/LICENSE</PackageLicenseUrl>
|
||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netstandard1.3' ">$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
|
||||
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.3' ">1.6.1</NetStandardImplicitPackageVersion>
|
||||
<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
|
||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\Microsoft.Azure.ServiceBus.KeyVault.xml</DocumentationFile>
|
||||
<DebugType>full</DebugType>
|
||||
<RootNamespace>Microsoft.Azure.ServiceBus.Plugins</RootNamespace>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.KeyVault" Version="2.0.6" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.13.9" />
|
||||
<PackageReference Include="Microsoft.Azure.ServiceBus" Version="0.0.6-preview" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Microsoft.Azure.ServiceBus.KeyVaultPlugin")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a042adf0-ef65-4f87-b634-322a409f3d61")]
|
||||
|
||||
// Friend Assemblies
|
||||
[assembly: InternalsVisibleTo("Microsoft.Azure.ServiceBus.KeyVault.Test,PublicKey=" +
|
||||
"0024000004800000940000000602000000240000525341310004000001000100fdf4acac3b2244" +
|
||||
"dd8a96737e5385b31414369dc3e42f371172127252856a0650793e1f5673a16d5d78e2ac852a10" +
|
||||
"4bc51e6f018dca44fdd26a219c27cb2b263956a80620223c8e9c2f8913c3c903e1e453e9e4e840" +
|
||||
"98afdad5f4badb8c1ebe0a7b0a4b57a08454646a65886afe3e290a791ff3260099ce0edf0bdbcc" +
|
||||
"afadfeb6")]
|
|
@ -1,100 +0,0 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.Plugins {
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Azure.ServiceBus.KeyVault.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An exception occured while trying to decrypt a message.
|
||||
/// </summary>
|
||||
public static string AfterMessageReceiveException
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("AfterMessageReceiveException", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Could not acquire Azure AD token for KeyVault access. KeyVault: '{0}'.
|
||||
/// </summary>
|
||||
public static string AzureAdTokenAcquisitionFailure {
|
||||
get {
|
||||
return ResourceManager.GetString("AzureAdTokenAcquisitionFailure", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An exception occured while trying to encrypt a message.
|
||||
/// </summary>
|
||||
public static string BeforeMessageSendException
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("BeforeMessageSendException", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Could not acquire KeyVault token. Token name: '{0}' KeyVault: '{1}'.
|
||||
/// </summary>
|
||||
public static string KeyVaultKeyAcquisitionFailure {
|
||||
get {
|
||||
return ResourceManager.GetString("KeyVaultKeyAcquisitionFailure", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AfterMessageReceiveException" xml:space="preserve">
|
||||
<value>An exception occured while trying to decrypt a message.</value>
|
||||
</data>
|
||||
<data name="AzureAdTokenAcquisitionFailure" xml:space="preserve">
|
||||
<value>Could not acquire Azure AD token for KeyVault access. KeyVault: '{0}'</value>
|
||||
</data>
|
||||
<data name="BeforeMessageSendException" xml:space="preserve">
|
||||
<value>An exception occured while trying to encrypt a message.</value>
|
||||
</data>
|
||||
<data name="KeyVaultKeyAcquisitionFailure" xml:space="preserve">
|
||||
<value>Could not acquire KeyVault token. Token name: '{0}'. Token Version: '{1}'. KeyVault: '{1}'.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -1,31 +0,0 @@
|
|||
# Key Vault plugin for Azure Service Bus
|
||||
|
||||
The Key Vault plugin for Azure Service Bus allows for the message body to be encrypted and decrypted by registering a plugin and its accompanying settings.
|
||||
|
||||
## How to use
|
||||
|
||||
In order to use this plugin you will need to setup the following:
|
||||
|
||||
1. An Azure subscription
|
||||
|
||||
1. A Service Bus namespace
|
||||
|
||||
1. [A Key Vault instance](https://docs.microsoft.com/azure/key-vault/key-vault-get-started)
|
||||
|
||||
1. [An Azure Active Directory application](https://docs.microsoft.com/azure/key-vault/key-vault-get-started#a-idregisteraregister-an-application-with-azure-active-directory)
|
||||
|
||||
## Example
|
||||
|
||||
Below is a simple example of how to use the plugin.
|
||||
|
||||
```csharp
|
||||
var keyVaultSettings = new KeyVaultPluginSettings("{AADClientID}", "{KeyVaultEndpoint}", "{AADSecret}");
|
||||
var keyVaultPlugin = new KeyVaultPlugin("{KeyVaultSecretName}", "{KeyVaultSecretVersion}", keyVaultSettings);
|
||||
|
||||
var queueClient = new QueueClient("{ServiceBusConnectionString}", "{ServiceBusEntityName}");
|
||||
queueClient.RegisterPlugin(keyVaultPlugin);
|
||||
|
||||
var message = new Message(Encoding.UTF8.GetBytes("Super secret message"));
|
||||
|
||||
await queueClient.SendAsync(message).ConfigureAwait(false);
|
||||
```
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.KeyVault.Test
|
||||
{
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.ServiceBus.Plugins;
|
||||
using Microsoft.Azure.ServiceBus.Test.Shared;
|
||||
using Xunit;
|
||||
|
||||
public class EncryptionTests
|
||||
{
|
||||
[Fact]
|
||||
[DisplayTestMethodName]
|
||||
public async Task SmokeTest()
|
||||
{
|
||||
var payload = Encoding.UTF8.GetBytes("hello");
|
||||
var password = "password";
|
||||
|
||||
byte[] hash = null;
|
||||
using (var sha256 = SHA256.Create())
|
||||
{
|
||||
hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
|
||||
}
|
||||
|
||||
var iV = KeyVaultPlugin.GenerateInitializationVector();
|
||||
var encryptedPayload = await KeyVaultPlugin.Encrypt(payload, hash, iV);
|
||||
var decryptedPayload = await KeyVaultPlugin.Decrypt(encryptedPayload, hash, iV);
|
||||
|
||||
Assert.Equal(payload, decryptedPayload);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[DisplayTestMethodName]
|
||||
public async Task MockSecretManager()
|
||||
{
|
||||
var secretManager = new MockSecretManager();
|
||||
|
||||
var keyVaultPlugin = new KeyVaultPlugin("service-bus", secretManager);
|
||||
|
||||
var messageBody = Encoding.UTF8.GetBytes("hi");
|
||||
|
||||
var message = new Message(messageBody);
|
||||
|
||||
var encryptedMessage = await keyVaultPlugin.BeforeMessageSend(message);
|
||||
var decryptedMessage = await keyVaultPlugin.AfterMessageReceive(encryptedMessage);
|
||||
Assert.Equal(messageBody, decryptedMessage.Body);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyTitle>Microsoft.Azure.ServiceBus.KeyVault.Test</AssemblyTitle>
|
||||
<TargetFrameworks>netcoreapp1.0;net46</TargetFrameworks>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<AssemblyName>Microsoft.Azure.ServiceBus.KeyVault.Test</AssemblyName>
|
||||
<AssemblyOriginatorKeyFile>../../build/keyfile.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
<PackageId>Microsoft.Azure.ServiceBus.KeyVault.Test</PackageId>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50;portable-net46+win8</PackageTargetFallback>
|
||||
<RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
|
||||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
|
||||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
|
||||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
|
||||
<Description />
|
||||
<DelaySign>False</DelaySign>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.Azure.ServiceBus.KeyVaultPlugin\Microsoft.Azure.ServiceBus.KeyVaultPlugin.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.Azure.ServiceBus.Test.Shared\Microsoft.Azure.ServiceBus.Test.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.NETCore.Platforms" Version="1.1.0" />
|
||||
<PackageReference Include="xunit" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace Microsoft.Azure.ServiceBus.KeyVault.Test
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.ServiceBus.Plugins;
|
||||
|
||||
internal class MockSecretManager : ISecretManager
|
||||
{
|
||||
private Dictionary<string, byte[]> secretCache = new Dictionary<string, byte[]>();
|
||||
|
||||
public Task<byte[]> GetHashedSecret(string secretName, string secretVersion)
|
||||
{
|
||||
var combinedNameAndVersion = FormatSecretNameAndVersion(secretName, secretVersion);
|
||||
if (secretCache.ContainsKey(combinedNameAndVersion))
|
||||
{
|
||||
return Task.FromResult(secretCache[combinedNameAndVersion]);
|
||||
}
|
||||
|
||||
var secret = GenerateSecret();
|
||||
|
||||
using (var sha256 = SHA256.Create())
|
||||
{
|
||||
var secretAsBytes = Encoding.UTF8.GetBytes(secret);
|
||||
var hashedSecret = sha256.ComputeHash(secretAsBytes);
|
||||
secretCache.Add(combinedNameAndVersion, hashedSecret);
|
||||
return Task.FromResult(hashedSecret);
|
||||
}
|
||||
}
|
||||
|
||||
private string FormatSecretNameAndVersion(string secretName, string secretVersion)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(secretVersion))
|
||||
{
|
||||
return secretName;
|
||||
}
|
||||
return string.Concat(secretName, "_", secretVersion);
|
||||
}
|
||||
|
||||
private string GenerateSecret()
|
||||
{
|
||||
return "password";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Microsoft.Azure.ServiceBus.KeyVault.Test")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("bda98e20-3a26-4a5a-9371-cb02b73e3434")]
|
||||
|
||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
Загрузка…
Ссылка в новой задаче