Compartir a través de


Cómo conectarse a una base de datos desde una función de Azure usando Azure Key Vault (es-MX)

Artículo Original. https://blogs.msdn.microsoft.com/benjaminperkins/2018/06/13/how-to-connect-to-a-database-from-an-azure-function-using-azure-key-vault/

En el artículo original aquí donde almacenamos la cadena de conexión de la base de datos en una variable de entorno que ya no es un enfoque óptimo (era solo por ejemplo). Ahora actualizaremos la función de Azure para acceder a un secreto de Azure Key Vault que tiene la cadena de conexión de la base de datos y la usaremos para establecer la conexión a la base de datos. Vea estos artículos para obtener más información sobre los pasos que tomé para llegar hasta aquí.

Hay 3 pasos que debemos seguir para que esto suceda:

  1. Obtener un token de autenticación
  2. Obtenga el secreto
  3. Use el valor del secreto como la cadena de conexión de la base de datos

Reconocemos que este código no se está ejecutando en una estación de trabajo, por lo que no tiene acceso a nuestra identidad, ni proporcionaremos nuestra identidad a la aplicación Azure Function para obtener el token. En cambio, en pasos anteriores, hemos creado un MSI para la aplicación Azure Function y hemos otorgado ese acceso de lectura principal a Azure Key Vault. Por lo tanto, el token verifica la identidad de la aplicación Azure Function y no de ningún individuo.

Aquí está el fragmento de código que usé para obtener el token en nombre de la aplicación Azure Function.

public static async Task<string> GetToken(string resource, string apiversion)
{
  string msiEndpoint = Environment.GetEnvironmentVariable("MSI_ENDPOINT");
  string endpoint = "{msiEndpoint}/?resource={resource}&api-version={apiversion}";
  string msiSecret = Environment.GetEnvironmentVariable("MSI_SECRET");
  tokenClient.DefaultRequestHeaders.Add("Secret", msiSecret);
  JObject tokenServiceResponse = JsonConvert
      .DeserializeObject<JObject>(await tokenClient.GetStringAsync(endpoint));
  return tokenServiceResponse["access_token"].ToString();
}

El primer desafío que tuvimos fue averiguar MSI_ENDPOINT y MSI_SECRET. Después de algunas búsquedas, los encontré en la lista de variables de entorno a través de KUDU / SCM, que analizo más aquí. Ver la Figura 1 para un ejemplo.

https://msdnshared.blob.core.windows.net/media/2018/05/image_thumb1_thumb.png

MSI_ENDPOINT y MSI_SECRET se crean cuando activa MSI para el recurso de Azure, como mencionamos aquí.

El segundo fragmento de código usa el token y mantiene en secreto el valor de Azure Key Vault.

public static async Task<string> GetSecret(string secretName, string token, string apiversion)
{
  string kvURL = "https://??**??.vault.azure.net/";
  string endpoint = $"{kvURL}secrets/{secretName}?api-version={apiversion}";
  keyVaultClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
  JObject keyVaulteResponse = JsonConvert
     .DeserializeObject<JObject>(await keyVaultClient.GetStringAsync(endpoint));
  return keyVaulteResponse["value"].ToString();
}

El secretName nuevamente fue un poco difícil de encontrar y corregir, pero lo encontramos haciendo clic en los detalles secretos de Azure Key Vault y analizamos el contenido del Identificador secreto, como se ve en la Figura 2.

https://msdnshared.blob.core.windows.net/media/2018/05/image_thumb29_thumb_thumb.png

Figura 2, ¿cuál es la URL del punto final de Azure Key Vault, URL del punto final de Azure Key Vault?

Y el fragmento de código final que llama a los métodos anteriores y usa el secreto como la cadena de conexión se muestra aquí.

var token = await GetToken("https://vault.azure.net", "2017-09-01");
var secret = await GetSecret("<secretName>", token, "2016-10-01");
connection.ConnectionString = secret;
await connection.OpenAsync();

Y eso es todo, esta es una buena forma muy segura de proteger contraseñas y secretos que se filtran en su código fuente para que todos puedan ver.