Migración de una aplicación para usar conexiones sin contraseña con Azure Database for MySQL

En este artículo se explica cómo migrar de métodos de autenticación tradicionales a conexiones sin contraseña más seguras con Azure Database for MySQL.

Las solicitudes de aplicación a Azure Database for MySQL deben autenticarse. Azure Database for MySQL proporciona varias maneras diferentes para que las aplicaciones se conecten de forma segura. Una de las maneras es usar contraseñas. Sin embargo, debe priorizar las conexiones sin contraseña en las aplicaciones siempre que sea posible.

Comparación de las opciones de autenticación

Cuando la aplicación se autentica con Azure Database for MySQL, proporciona un par de nombre de usuario y contraseña para conectarse a la base de datos. Dependiendo de dónde se almacenen las identidades, hay dos tipos de autenticación: autenticación de Microsoft Entra y autenticación mySQL.

Autenticación de Microsoft Entra

La autenticación de Microsoft Entra es un mecanismo para conectarse a Azure Database for MySQL mediante identidades definidas en microsoft Entra ID. Con la autenticación de Microsoft Entra, puede administrar las identidades de los usuarios de la base de datos y otros servicios de Microsoft en una ubicación central, lo que simplifica la administración de permisos.

El uso de Microsoft Entra ID para la autenticación proporciona las siguientes ventajas:

  • Autenticación de usuarios en los servicios de Azure de forma uniforme.
  • Administración de directivas de contraseñas y rotación de contraseñas en un solo lugar.
  • Varias formas de autenticación admitidas por el identificador de Entra de Microsoft, que pueden eliminar la necesidad de almacenar contraseñas.
  • Los clientes pueden administrar permisos de base de datos mediante grupos externos (Id. de Microsoft Entra).
  • La autenticación de Microsoft Entra usa usuarios de base de datos MySQL para autenticar identidades en el nivel de base de datos.
  • Compatibilidad con la autenticación basada en tokens para aplicaciones que se conectan a Azure Database for MySQL.

Autenticación de MySQL

Puede crear cuentas en MySQL. Si decide usar contraseñas como credenciales para las cuentas, estas credenciales se almacenarán en la tabla user. Dado que estas contraseñas se almacenan en MySQL, debe administrar la rotación de las contraseñas por su cuenta.

Aunque es posible conectarse a Azure Database for MySQL con contraseñas, debe usarlos con precaución. Debe ser diligente para no exponer nunca las contraseñas en una ubicación no segura. Cualquier persona que obtenga acceso a las contraseñas puede autenticarse. Por ejemplo, existe el riesgo de que un usuario malintencionado pueda acceder a la aplicación si un cadena de conexión se comprueba accidentalmente en el control de código fuente, se envía a través de un correo electrónico no seguro, pegado en el chat incorrecto o visto por alguien que no debe tener permiso. En su lugar, considere la posibilidad de actualizar la aplicación para usar conexiones sin contraseña.

Introducción a las conexiones sin contraseña

Con una conexión sin contraseña, puede conectarse a servicios de Azure sin almacenar credenciales en el código de la aplicación, sus archivos de configuración o en variables de entorno.

Muchos servicios de Azure admiten conexiones sin contraseña, por ejemplo a través de Azure Managed Identity. Estas técnicas proporcionan características de seguridad sólidas que puede implementar mediante DefaultAzureCredential desde las bibliotecas cliente de Azure Identity. En este tutorial, aprenderá a actualizar una aplicación existente para usarla DefaultAzureCredential en lugar de alternativas como cadena de conexión s.

DefaultAzureCredential admite varios métodos de autenticación y determina automáticamente qué se debe usar en tiempo de ejecución. Este enfoque permite que la aplicación use diferentes métodos de autenticación en distintos entornos (desarrollo local frente a producción) sin implementar código específico del entorno.

El orden y las ubicaciones en las que DefaultAzureCredential se buscan credenciales se pueden encontrar en la información general de la biblioteca de identidades de Azure. Por ejemplo, al trabajar localmente, DefaultAzureCredential normalmente se autenticará con la cuenta que el desarrollador usó para iniciar sesión en Visual Studio. Cuando la aplicación se implemente en Azure, DefaultAzureCredential cambiará automáticamente para usar una identidad administrada. No se necesitan cambios de código para esta transición.

Para asegurarse de que las conexiones no tienen contraseña, debe tener en cuenta tanto el desarrollo local como el entorno de producción. Si se requiere una cadena de conexión en cualquier lugar, la aplicación no tiene contraseña.

En el entorno de desarrollo local, puede autenticarse con la CLI de Azure, Azure PowerShell, Visual Studio o complementos de Azure para Visual Studio Code o IntelliJ. En este caso, puede usar esa credencial en la aplicación en lugar de configurar propiedades.

Al implementar aplicaciones en un entorno de hospedaje de Azure, como una máquina virtual, puede asignar una identidad administrada en ese entorno. A continuación, no tendrá que proporcionar credenciales para conectarse a los servicios de Azure.

Nota:

Una identidad administrada proporciona una identidad de seguridad para representar una aplicación o servicio. La identidad está administrada por la plataforma Azure y no requiere que aprovisione o rote los secretos. Puede obtener más información sobre las identidades administradas en la documentación de información general.

Migración de una aplicación existente para usar conexiones sin contraseña

En los pasos siguientes se explica cómo migrar una aplicación existente para usar conexiones sin contraseña en lugar de una solución basada en contraseña.

0) Preparar el entorno de trabajo

En primer lugar, use el siguiente comando para configurar algunas variables de entorno.

export AZ_RESOURCE_GROUP=<YOUR_RESOURCE_GROUP>
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=demo
export AZ_MYSQL_AD_NON_ADMIN_USERNAME=<YOUR_AZURE_AD_NON_ADMIN_USER_DISPLAY_NAME>
export AZ_MYSQL_AD_MI_USERNAME=<YOUR_AZURE_AD_MI_DISPLAY_NAME>
export AZ_USER_IDENTITY_NAME=<YOUR_USER_ASSIGNED_MANAGEMED_IDENTITY_NAME>
export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName --output tsv)
export CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id --output tsv)

Reemplace los marcadores de posición por los valores siguientes, que se usan a lo largo de este artículo:

  • <YOUR_RESOURCE_GROUP>: el nombre del grupo de recursos en el que se encuentran los recursos.
  • <YOUR_DATABASE_SERVER_NAME>: el nombre del servidor de MySQL, que debe ser único en Azure.
  • <YOUR_AZURE_AD_NON_ADMIN_USER_DISPLAY_NAME>: nombre para mostrar del usuario que no es administrador de Microsoft Entra. Asegúrese de que el nombre es un usuario válido en el inquilino de Microsoft Entra.
  • <YOUR_AZURE_AD_MI_DISPLAY_NAME>: nombre para mostrar del usuario de Microsoft Entra para la identidad administrada. Asegúrese de que el nombre es un usuario válido en el inquilino de Microsoft Entra.
  • <YOUR_USER_ASSIGNED_MANAGEMED_IDENTITY_NAME>: el nombre del servidor de identidad administrada asignado por el usuario, que debe ser único en Azure.

1) Configuración de Azure Database for MySQL

1.1) Habilitación de la autenticación basada en identificadores de Microsoft Entra

Para usar el acceso de Id. de Microsoft Entra con Azure Database for MySQL, debe establecer primero el usuario administrador de Microsoft Entra. Solo un usuario de Microsoft Entra Administración puede crear o habilitar usuarios para la autenticación basada en identificadores de Microsoft Entra.

Si usa la CLI de Azure, ejecute el siguiente comando para asegurarse de que tiene permisos suficientes:

az login --scope https://graph.microsoft.com/.default

Ejecute el siguiente comando para crear la identidad de usuario para asignar:

az identity create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_USER_IDENTITY_NAME

Importante

Después de crear la identidad asignada por el usuario, pida al administrador global o administrador de roles con privilegios que conceda los siguientes permisos para esta identidad: User.Read.All, GroupMember.Read.Ally Application.Read.ALL. Para obtener más información, consulte la sección Permisos de autenticación de Active Directory.

Ejecute el siguiente comando para asignar la identidad al servidor MySQL para crear el administrador de Microsoft Entra:

az mysql flexible-server identity assign \
    --resource-group $AZ_RESOURCE_GROUP \
    --server-name $AZ_DATABASE_SERVER_NAME \
    --identity $AZ_USER_IDENTITY_NAME

A continuación, ejecute el siguiente comando para establecer el administrador de Microsoft Entra:

az mysql flexible-server ad-admin create \
    --resource-group $AZ_RESOURCE_GROUP \
    --server-name $AZ_DATABASE_SERVER_NAME \
    --display-name $CURRENT_USERNAME \
    --object-id $CURRENT_USER_OBJECTID \
    --identity $AZ_USER_IDENTITY_NAME

Este comando establecerá el administrador de Microsoft Entra en el usuario que ha iniciado sesión actual.

Nota:

Solo puede crear un administrador de Microsoft Entra por servidor MySQL. La selección de otra sobrescribirá el administrador existente de Microsoft Entra configurado para el servidor.

2) Configuración de Azure Database for MySQL para el desarrollo local

2.1) Configuración de una regla de firewall para la dirección IP local

De forma predeterminada, las instancias de Azure Database for MySQL están protegidas. Tienen un firewall que no permite ninguna conexión entrante.

Puede omitir este paso si está usando Bash porque el comando flexible-server create ya detectó su dirección IP local y la estableció en el servidor MySQL.

Si se conecta al servidor MySQL desde Subsistema de Windows para Linux (WSL) en un equipo Windows, debe agregar el identificador de host de WSL al firewall. Para obtener la dirección IP de la máquina host, ejecute el siguiente comando en WSL:

cat /etc/resolv.conf

Copie la dirección IP que sigue al término nameservery, a continuación, use el siguiente comando para establecer una variable de entorno para la dirección IP de WSL:

export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

A continuación, use el siguiente comando para abrir el firewall del servidor en la aplicación basada en WSL:

az mysql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip-wsl \
    --server $AZ_DATABASE_SERVER_NAME \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --output tsv

2.2) Creación de un usuario que no es administrador de MySQL y concesión de permiso

A continuación, cree un usuario que no sea administrador de Microsoft Entra y conceda todos los permisos en la $AZ_DATABASE_NAME base de datos. Puede cambiar el nombre $AZ_DATABASE_NAME de la base de datos para que se ajuste a sus necesidades.

Cree un script SQL denominado create_ad_user.sql para crear un usuario que no sea administrador. Agregue el siguiente contenido y guárdelo de forma local:

export AZ_MYSQL_AD_NON_ADMIN_USERID=$(az ad signed-in-user show --query id --output tsv)

cat << EOF > create_ad_user.sql
SET aad_auth_validate_oids_in_tenant = OFF;
CREATE AADUSER '$AZ_MYSQL_AD_NON_ADMIN_USERNAME' IDENTIFIED BY '$AZ_MYSQL_AD_NON_ADMIN_USERID';
GRANT ALL PRIVILEGES ON $AZ_DATABASE_NAME.* TO '$AZ_MYSQL_AD_NON_ADMIN_USERNAME'@'%';
FLUSH privileges;
EOF

A continuación, use el siguiente comando para ejecutar el script SQL para crear el usuario que no es administrador de Microsoft Entra:

mysql -h $AZ_DATABASE_SERVER_NAME.mysql.database.azure.com --user $CURRENT_USERNAME --enable-cleartext-plugin --password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) < create_ad_user.sql

Ahora use el siguiente comando para quitar el archivo de script SQL temporal:

rm create_ad_user.sql

Nota:

Puede leer información más detallada sobre cómo crear usuarios de MySQL en Creación de usuarios en Azure Database for MySQL.

3) Iniciar sesión y migrar el código de la aplicación para usar conexiones sin contraseña

Para el desarrollo local, asegúrese de que está autenticado con la misma cuenta de Microsoft Entra a la que asignó el rol en MySQL. Puede autenticarse a través de la CLI de Azure, Visual Studio, Azure PowerShell u otras herramientas, como IntelliJ.

Inicie sesión en Azure a través de la CLI de Azure mediante el comando siguiente:

az login

A continuación, siga estos pasos para actualizar el código para usar conexiones sin contraseña. Aunque conceptualmente es similar, cada lenguaje usa detalles de implementación diferentes.

  1. Dentro del proyecto, agregue la siguiente referencia al azure-identity-extensions paquete. Esta biblioteca contiene todas las entidades necesarias para implementar conexiones sin contraseña.

    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-identity-extensions</artifactId>
        <version>1.0.0</version>
    </dependency>
    
  2. Habilite el complemento de autenticación de Azure MySQL en la dirección URL de JDBC. Identifique las ubicaciones del código que actualmente crean un java.sql.Connection para conectarse a Azure Database for MySQL. Actualice url y user en el archivo application.properties para que coincida con los siguientes valores:

    url=jdbc:mysql://$AZ_DATABASE_SERVER_NAME.mysql.database.azure.com:3306/$AZ_DATABASE_NAME?serverTimezone=UTC&sslMode=REQUIRED&defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
    user=$AZ_MYSQL_AD_NON_ADMIN_USERNAME
    

    Nota:

    Si usa la MysqlConnectionPoolDataSource clase como origen de datos en la aplicación, asegúrese de quitar defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin de la dirección URL.

    url=jdbc:mysql://$AZ_DATABASE_SERVER_NAME.mysql.database.azure.com:3306/$AZ_DATABASE_NAME?serverTimezone=UTC&sslMode=REQUIRED&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
    user=$AZ_MYSQL_AD_NON_ADMIN_USERNAME
    
  3. Reemplace la variable one $AZ_DATABASE_SERVER_NAME , una $AZ_DATABASE_NAME variable y una $AZ_MYSQL_AD_NON_ADMIN_USERNAME variable por los valores que configuró al principio de este artículo.

  4. Quite de password la dirección URL de JDBC.

Ejecución de la aplicación de forma local

Después de realizar estos cambios de código, ejecute la aplicación localmente. La nueva configuración debe recoger las credenciales locales si ha iniciado sesión en un IDE compatible o una herramienta de línea de comandos, como la CLI de Azure, Visual Studio o IntelliJ. Los roles que asigne al usuario de desarrollo local en Azure permitirán a la aplicación conectarse al servicio de Azure localmente.

4) Configuración del entorno de hospedaje de Azure

Una vez configurada la aplicación para usar conexiones sin contraseña y se ejecuta localmente, el mismo código se puede autenticar en los servicios de Azure después de implementarse en Azure. Por ejemplo, una aplicación implementada en una instancia de servicio de App de Azure que tiene asignada una identidad administrada puede conectarse a Azure Storage.

En esta sección, ejecutará dos pasos para permitir que la aplicación se ejecute en un entorno de hospedaje de Azure de forma sin contraseña:

  • Asigne la identidad administrada para el entorno de hospedaje de Azure.
  • Asigne roles a la identidad administrada.

Nota:

Azure también proporciona service Conectar or, que puede ayudarle a conectar el servicio de hospedaje con PostgreSQL. Con Service Conectar or para configurar el entorno de hospedaje, puede omitir el paso de asignar roles a la identidad administrada porque Service Conectar or lo hará automáticamente. En la sección siguiente se describe cómo configurar el entorno de hospedaje de Azure de dos maneras: una a través de Service Conectar or y la otra configurando directamente cada entorno de hospedaje.

Importante

Los comandos de Service Conectar or requieren la CLI de Azure 2.41.0 o posterior.

Asignación de la identidad administrada mediante Azure Portal

En los pasos siguientes se muestra cómo asignar una identidad administrada asignada por el sistema para varios servicios de hospedaje web. La identidad administrada puede conectarse de manera segura a otros servicios de Azure mediante las configuraciones de aplicación que configuró anteriormente.

  1. En la página de información general principal de la instancia de servicio de App de Azure, seleccione Identidad en el panel de navegación.

  2. En la pestaña Asignado por el sistema, asegúrese de establecer el campo Estado en activado. Azure administra internamente una identidad asignada por el sistema y controla las tareas administrativas. Los detalles y los id. de la identidad nunca se exponen en el código.

    Screenshot of Azure portal Identity page of App Service resource with System assigned tab showing and Status field highlighted.

También puede asignar una identidad administrada en un entorno de hospedaje de Azure mediante la CLI de Azure.

Puede asignar una identidad administrada a una instancia de servicio de App de Azure con el comando az webapp identity assign, como se muestra en el ejemplo siguiente:

export AZ_MI_OBJECT_ID=$(az webapp identity assign \
    --resource-group $AZ_RESOURCE_GROUP \
    --name <service-instance-name> \
    --query principalId \
    --output tsv)

Asignación de roles a la identidad administrada

A continuación, conceda permisos a la identidad administrada que asignó para acceder a la instancia de MySQL.

Estos pasos crearán un usuario de Microsoft Entra para la identidad administrada y le concederán todos los permisos para la base de datos $AZ_DATABASE_NAME . Puede cambiar el nombre $AZ_DATABASE_NAME de la base de datos para que se ajuste a sus necesidades.

En primer lugar, cree un script SQL denominado create_ad_user.sql para crear un usuario que no sea administrador. Agregue el siguiente contenido y guárdelo de forma local:

export AZ_MYSQL_AD_MI_USERID=$(az ad sp show --id $AZ_MI_OBJECT_ID --query appId --output tsv)

cat << EOF > create_ad_user.sql
SET aad_auth_validate_oids_in_tenant = OFF;
CREATE AADUSER '$AZ_MYSQL_AD_MI_USERNAME' IDENTIFIED BY '$AZ_MYSQL_AD_MI_USERID';
GRANT ALL PRIVILEGES ON $AZ_DATABASE_NAME.* TO '$AZ_MYSQL_AD_MI_USERNAME'@'%';
FLUSH privileges;
EOF

A continuación, use el siguiente comando para ejecutar el script SQL para crear el usuario que no es administrador de Microsoft Entra:

mysql -h $AZ_DATABASE_SERVER_NAME.mysql.database.azure.com --user $CURRENT_USERNAME --enable-cleartext-plugin --password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) < create_ad_user.sql

Ahora use el siguiente comando para quitar el archivo de script SQL temporal:

rm create_ad_user.sql

Probar la aplicación

Antes de implementar la aplicación en el entorno de hospedaje, debe realizar un cambio más en el código porque la aplicación se va a conectar a MySQL mediante el usuario creado para la identidad administrada.

Actualice el código para usar el usuario creado para la identidad administrada:

properties.put("user", "$AZ_MYSQL_AD_MI_USERNAME");

Después de realizar estos cambios en el código, puede compilar y volver a implementar la aplicación. A continuación, vaya a la aplicación hospedada en el explorador. La aplicación debe poder conectarse correctamente a la base de datos MySQL. Tenga en cuenta que las asignaciones de roles pueden tardar varios minutos en propagarse a través del entorno de Azure. Ahora la aplicación está configurada para ejecutarse localmente y en un entorno de producción sin que los desarrolladores tengan que administrar los secretos en la propia aplicación.

Pasos siguientes

En este tutorial, ha aprendido a migrar una aplicación a conexiones sin contraseña.

Puede leer los siguientes recursos para explorar los conceptos que se describen en este artículo con más detalle: