问题
I am attempting to put some output from a service I am running in a Key Vault in Azure. The output of my service will be user credentials which is why I want to use Key Vault for this purpose.
So far, I have tried the KeyVaultClient's SetSecretAsync method, but it's not working for me, I am not getting any error messages however I'm also not seeing a new secret created in my targetted KeyVault. I have not been able to find a KeyVaultClient Add Secret method as it does not exist, am I using the right object/method here?
The method in question here is AddResult.
Here is my code:
private static AzureKeyVault instance;
private static KeyVaultClient client;
private AzureKeyVault()
{
//initialize the azure key vault
var vaultAddress = ConfigurationManager.AppSettings["VaultUri"];
client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken));
}
public static async Task<string> GetAccessToken(string authority, string resource, string scope)
{
var clientId = ConfigurationManager.AppSettings["ClientID"];
var clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
var result = await context.AcquireTokenAsync(resource, clientCredential);
return result.AccessToken;
}
public static AzureKeyVault GetInstance
{
get
{
if (instance == null)
{
instance = new AzureKeyVault();
}
return instance;
}
}
public void AddResult(string machineIPAndPort, BruteForceResult result)
{
client.SetSecretAsync("https://vaultURI(redacted).vault.azure.net/", machineIPAndPort, JsonConvert.SerializeObject(result));
}
回答1:
Use patience (await creation).
// Let's create a secret and read it back
string vaultBaseUrl = "https://alice.vault.azure.net";
string secret = "from-NET-SDK";
// Await SetSecretAsync
KeyVaultClient keyclient = new KeyVaultClient(GetToken);
var result = keyclient.SetSecretAsync(vaultBaseUrl, secret, "Sup3eS3c5et").Result;
// Print indented JSON response
string prettyResult = JsonConvert.SerializeObject(result, Formatting.Indented);
Console.WriteLine($"SetSecretAsync completed: {prettyResult}\n");
// Read back secret
string secretUrl = $"{vaultBaseUrl}/secrets/{secret}";
var secretWeJustWroteTo = keyclient.GetSecretAsync(secretUrl).Result;
Console.WriteLine($"secret: {secretWeJustWroteTo.Id} = {secretWeJustWroteTo.Value}");
Result:
SetSecretAsync completed:
{
"SecretIdentifier":{
"BaseIdentifier":"https://alice.vault.azure.net:443/secrets/from-NET-SDK",
"Identifier":"https://alice.vault.azure.net:443/secrets/from-NET-SDK/59793...",
"Name":"from-NET-SDK",
"Vault":"https://alice.vault.azure.net:443",
"VaultWithoutScheme":"alice.vault.azure.net",
"Version":"597930b70565447d8ba9ba525a206a9e"
},
"value":"Sup3eS3c5et",
"id":"https://alice.vault.azure.net/secrets/from-NET-SDK/59...",
"contentType":null,
"attributes":{
"recoveryLevel":"Purgeable",
"enabled":true,
"nbf":null,
"exp":null,
"created":1508354384,
"updated":1508354384
},
"tags":null,
"kid":null,
"managed":null
}
secret: https://alice.vault.azure.net/secrets/from-NET-SDK/59793... = Sup3eS3c5et
What you should really do is rewrite AddResult()
:
public bool AddResult(string machineIPAndPort, BruteForceResult result)
{
await result = client.SetSecretAsync("https://vaultURI(redacted).vault.azure.net/",
machineIPAndPort, JsonConvert.SerializeObject(result));
return true;
}
And maybe wrap that in a try-catch
and read the InnerException
since that's where the meaningful HTTP response body will be. For example, making the request against a Key Vault i don't have access to results in:
And also because this is the cloud, you're in for fierce competition with other mission critical traffic, things will fail.
来源:https://stackoverflow.com/questions/46816697/programatically-adding-secrets-to-key-vault-in-c-sharp