Azure Database for MySQL에서 암호 없는 연결을 사용하도록 애플리케이션 마이그레이션

이 문서에서는 Azure Database for MySQL을 사용하여 기존의 인증 방법에서 보다 안전하고 암호 없는 연결로 마이그레이션하는 방법을 설명합니다.

Azure Database for MySQL에 대한 애플리케이션 요청은 인증되어야 합니다. Azure Database for MySQL은 앱이 안전하게 연결하는 여러 가지 방법을 제공합니다. 방법 중 하나는 암호를 사용하는 것입니다. 그러나 가능한 경우 애플리케이션에서 암호 없는 연결에 대한 우선 순위를 지정해야 합니다.

인증 옵션 비교

애플리케이션이 Azure Database for MySQL을 사용하여 인증하는 경우 데이터베이스에 연결할 사용자 이름과 암호 쌍을 제공합니다. ID가 저장되는 위치에 따라 Microsoft Entra 인증 및 MySQL 인증의 두 가지 인증 유형이 있습니다.

Microsoft Entra 인증

Microsoft Entra 인증은 Microsoft Entra ID에 정의된 ID를 사용하여 Azure Database for MySQL에 연결하는 메커니즘입니다. Microsoft Entra 인증을 사용하면 중앙 위치에서 데이터베이스 사용자 ID 및 기타 Microsoft 서비스 관리할 수 있으므로 권한 관리가 간소화됩니다.

인증에 Microsoft Entra ID를 사용하면 다음과 같은 이점이 제공됩니다.

  • 균일한 방식으로 Azure Services에서 사용자 인증
  • 한 곳에서 암호 정책 및 암호 회전 관리
  • Microsoft Entra ID에서 지원하는 여러 형태의 인증으로 암호를 저장할 필요가 없습니다.
  • 고객은 외부(Microsoft Entra ID) 그룹을 사용하여 데이터베이스 권한을 관리할 수 있습니다.
  • Microsoft Entra 인증은 MySQL 데이터베이스 사용자를 사용하여 데이터베이스 수준에서 ID를 인증합니다.
  • Azure Database for MySQL에 연결하는 애플리케이션에 대한 토큰 기반 인증 지원

MySQL 인증

MySQL에서 계정을 만들 수 있습니다. 암호를 계정의 자격 증명으로 사용하도록 선택한 경우 이러한 자격 증명은 user 테이블에 저장됩니다. 이러한 암호는 MySQL에 저장되므로 암호 회전을 직접 관리해야 합니다.

암호를 사용하여 Azure Database for MySQL에 연결할 수 있지만 주의해서 사용해야 합니다. 안전하지 않은 위치에 암호를 노출하지 않도록 하려면 부지런해야 합니다. 암호에 대한 액세스 권한을 얻는 사람은 누구나 인증할 수 있습니다. 예를 들어 연결 문자열 실수로 소스 제어에 검사, 안전하지 않은 전자 메일을 통해 전송되거나, 잘못된 채팅에 붙여넣거나, 권한이 없어야 하는 사람이 볼 경우 악의적인 사용자가 애플리케이션에 액세스할 수 있는 위험이 있습니다. 대신 암호 없는 연결을 사용하도록 애플리케이션을 업데이트하는 것이 좋습니다.

암호 없는 연결 소개

암호 없는 연결을 사용하면 애플리케이션 코드, 구성 파일 또는 환경 변수에 자격 증명을 저장하지 않고도 Azure 서비스에 연결할 수 있습니다.

많은 Azure 서비스는 예를 들어 Azure 관리 ID를 통해 암호 없는 연결을 지원합니다. 이러한 기술은 Azure ID 클라이언트 라이브러리에서 DefaultAzureCredential을 사용하여 구현할 수 있는 강력한 보안 기능을 제공합니다. 이 자습서에서는 연결 문자열 같은 대안 대신 사용할 DefaultAzureCredential 기존 애플리케이션을 업데이트하는 방법을 알아봅니다.

DefaultAzureCredential은 여러 인증 방법을 지원하고 런타임에 사용해야 하는 방법을 자동으로 결정합니다. 이 방법을 사용하면 앱에서 환경별 코드를 구현하지 않고도 다양한 환경(로컬 개발 및 프로덕션)에서 다양한 인증 방법을 사용할 수 있습니다.

자격 증명을 검색하는 DefaultAzureCredential 순서 및 위치는 Azure ID 라이브러리 개요에서 찾을 수 있습니다. 예를 들어 로컬 DefaultAzureCredential 로 작업하는 경우 일반적으로 개발자가 Visual Studio에 로그인하는 데 사용한 계정을 사용하여 인증합니다. 앱이 Azure에 배포되면 DefaultAzureCredential에서 자동으로 관리 ID를 사용하도록 전환합니다. 이 전환에서는 코드를 변경할 필요가 없습니다.

연결이 암호 없는지 확인하려면 로컬 개발 및 프로덕션 환경을 모두 고려해야 합니다. 어느 곳에서든 연결 문자열 필요한 경우 애플리케이션은 암호가 없습니다.

로컬 개발 환경에서는 Azure CLI, Azure PowerShell, Visual Studio 또는 Visual Studio Code 또는 IntelliJ용 Azure 플러그 인으로 인증할 수 있습니다. 이 경우 속성을 구성하는 대신 애플리케이션에서 해당 자격 증명을 사용할 수 있습니다.

가상 머신과 같은 Azure 호스팅 환경에 애플리케이션을 배포할 때 해당 환경에서 관리 ID를 할당할 수 있습니다. 그런 다음 Azure 서비스에 연결하기 위해 자격 증명을 제공할 필요가 없습니다.

참고 항목

관리 ID는 앱 또는 서비스를 나타내는 보안 ID를 제공합니다. ID는 Azure 플랫폼에서 관리하며 비밀을 프로비전하거나 회전할 필요가 없습니다. 관리 ID는 개요 설명서에서 자세히 알아볼 수 있습니다.

암호 없는 연결을 사용하도록 기존 애플리케이션 마이그레이션

다음 단계에서는 암호 기반 솔루션 대신 암호 없는 연결을 사용하도록 기존 애플리케이션을 마이그레이션하는 방법을 설명합니다.

0) 작업 환경 준비

먼저 다음 명령을 사용하여 일부 환경 변수를 설정합니다.

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)

자리 표시자를 이 문서 전체에서 사용되는 다음 값으로 바꿉 있습니다.

  • <YOUR_RESOURCE_GROUP>: 리소스가 있는 리소스 그룹의 이름입니다.
  • <YOUR_DATABASE_SERVER_NAME>: Azure에서 고유해야 하는 MySQL 서버의 이름입니다.
  • <YOUR_AZURE_AD_NON_ADMIN_USER_DISPLAY_NAME>: Microsoft Entra 비관리자의 표시 이름입니다. 이름이 Microsoft Entra 테넌트에서 유효한 사용자인지 확인합니다.
  • <YOUR_AZURE_AD_MI_DISPLAY_NAME>: 관리 ID에 대한 Microsoft Entra 사용자의 표시 이름입니다. 이름이 Microsoft Entra 테넌트에서 유효한 사용자인지 확인합니다.
  • <YOUR_USER_ASSIGNED_MANAGEMED_IDENTITY_NAME>: Azure에서 고유해야 하는 사용자 할당 관리 ID 서버의 이름입니다.

1) Azure Database for MySQL 구성

1.1) Microsoft Entra ID 기반 인증 사용

Azure Database for MySQL에서 Microsoft Entra ID 액세스를 사용하려면 먼저 Microsoft Entra 관리 사용자를 설정해야 합니다. Microsoft Entra 관리 사용자만 Microsoft Entra ID 기반 인증에 대한 사용자를 만들거나 사용하도록 설정할 수 있습니다.

Azure CLI를 사용하는 경우 다음 명령을 실행하여 충분한 권한이 있는지 확인합니다.

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

다음 명령을 실행하여 할당할 사용자 ID를 만듭니다.

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

Important

사용자가 할당한 ID를 만든 후 전역 관리자 또는 권한 있는 역할 관리자에게 요청하여 이 ID에 대해 User.Read.All, GroupMember.Read.AllApplication.Read.ALL 권한을 부여합니다. 자세한 내용은 Active Directory 인증권한 섹션을 참조하세요.

다음 명령을 실행하여 Microsoft Entra 관리자를 만들기 위해 MySQL 서버에 ID를 할당합니다.

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

그런 다음, 다음 명령을 실행하여 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

이 명령은 Microsoft Entra 관리자를 현재 로그인한 사용자로 설정합니다.

참고 항목

MySQL 서버당 하나의 Microsoft Entra 관리자만 만들 수 있습니다. 다른 항목을 선택하면 서버에 대해 구성된 기존 Microsoft Entra 관리자가 덮어쓰입니다.

2) 로컬 개발을 위해 Azure Database for MySQL 구성

2.1) 로컬 IP에 대한 방화벽 규칙 구성

Azure Database for MySQL 인스턴스는 기본적으로 보호됩니다. 들어오는 연결을 허용하지 않는 방화벽이 있습니다.

flexible-server create 명령이 이미 로컬 IP 주소를 감지하고 MySQL 서버에 설정했기 때문에 Bash를 사용하는 경우 이 단계를 건너뛸 수 있습니다.

Windows 컴퓨터의 WSL(Linux용 Windows 하위 시스템)에서 MySQL 서버에 연결하는 경우 방화벽에 WSL 호스트 ID를 추가해야 합니다. WSL에서 다음 명령을 실행하여 호스트 머신의 IP 주소를 가져옵니다.

cat /etc/resolv.conf

용어 nameserver다음에 IP 주소를 복사한 다음, 다음 명령을 사용하여 WSL IP 주소에 대한 환경 변수를 설정합니다.

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

그런 다음, 다음 명령을 사용하여 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) MySQL 비관리자 사용자 만들기 및 권한 부여

다음으로, 관리자가 아닌 Microsoft Entra 사용자를 만들고 데이터베이스에 대한 $AZ_DATABASE_NAME 모든 권한을 부여합니다. 필요에 맞게 데이터베이스 이름을 $AZ_DATABASE_NAME 변경할 수 있습니다.

비관리 사용자를 만들기 위해 create_ad_user.sql이라는 SQL 스크립트를 만듭니다. 다음 콘텐츠를 추가하고 로컬에 저장합니다.

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

그런 다음, 다음 명령을 사용하여 SQL 스크립트를 실행하여 관리자가 아닌 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

이제 다음 명령을 사용하여 임시 SQL 스크립트 파일을 제거합니다.

rm create_ad_user.sql

참고 항목

Azure Database for MySQL에서 사용자 만들기에서 MySQL 사용자 만들기에 대한 자세한 내용을 읽을 수 있습니다.

3) 암호 없는 연결을 사용하도록 앱 코드 로그인 및 마이그레이션

로컬 개발의 경우 MySQL에서 역할을 할당한 것과 동일한 Microsoft Entra 계정으로 인증되었는지 확인합니다. Azure CLI, Visual Studio, Azure PowerShell 또는 기타 도구(예: IntelliJ)를 통해 인증할 수 있습니다.

다음 명령을 사용하여 Azure CLI를 통해 Azure에 로그인합니다.

az login

다음으로, 다음 단계를 사용하여 암호 없는 연결을 사용하도록 코드를 업데이트합니다. 개념적으로 비슷하지만 각 언어는 서로 다른 구현 세부 정보를 사용합니다.

  1. 프로젝트 내에서 패키지에 다음 참조를 azure-identity-extensions 추가합니다. 이 라이브러리에는 암호 없는 연결을 구현하는 데 필요한 모든 엔터티가 포함되어 있습니다.

    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-identity-extensions</artifactId>
        <version>1.0.0</version>
    </dependency>
    
  2. JDBC URL에서 Azure MySQL 인증 플러그 인을 사용하도록 설정합니다. 현재 Azure Database for MySQL에 연결할 위치를 만드는 java.sql.Connection 코드의 위치를 식별합니다. 다음 값과 user일치하도록 application.properties 파일을 업데이트 url 합니다.

    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
    

    참고 항목

    애플리케이션에서 클래스를 MysqlConnectionPoolDataSource 데이터 원본으로 사용하는 경우 URL에서 제거 defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin 해야 합니다.

    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. 변수 1개 $AZ_DATABASE_SERVER_NAME , 변수 1개 $AZ_DATABASE_NAME$AZ_MYSQL_AD_NON_ADMIN_USERNAME , 변수 1개를 이 문서의 시작 부분에서 구성한 값으로 바꿉다.

  4. password JDBC URL에서 제거합니다.

로컬에서 앱 실행하기

이러한 코드가 변경되면 애플리케이션을 로컬로 실행합니다. 호환되는 IDE 또는 명령줄 도구(예: Azure CLI, Visual Studio 또는 IntelliJ)에 로그인한 경우 새 구성에서 로컬 자격 증명을 선택해야 합니다. Azure에서 로컬 개발자 사용자에게 할당한 역할을 통해 앱에서 Azure 서비스에 로컬로 연결할 수 있습니다.

4) Azure 호스팅 환경 구성

애플리케이션이 암호 없는 연결을 사용하도록 구성되고 로컬로 실행되면 동일한 코드가 Azure에 배포된 후 Azure 서비스에 인증할 수 있습니다. 예를 들어 관리 ID가 할당된 Azure 앱 Service 인스턴스에 배포된 애플리케이션은 Azure Storage에 연결할 수 있습니다.

이 섹션에서는 두 단계를 실행하여 암호 없는 방식으로 Azure 호스팅 환경에서 애플리케이션을 실행할 수 있도록 합니다.

  • Azure 호스팅 환경에 대한 관리 ID를 할당합니다.
  • 관리 ID에 역할을 할당합니다.

참고 항목

또한 Azure는 PostgreSQL과 호스팅 서비스를 연결하는 데 도움이 되는 서비스 커넥트or를 제공합니다. 서비스 커넥트or를 사용하여 호스팅 환경을 구성하면 Service 커넥트or에서 작업을 수행하므로 관리 ID에 역할을 할당하는 단계를 생략할 수 있습니다. 다음 섹션에서는 두 가지 방법으로 Azure 호스팅 환경을 구성하는 방법에 대해 설명합니다. 하나는 서비스 커넥트or를 통해, 다른 하나는 각 호스팅 환경을 직접 구성하여 구성합니다.

Important

서비스 커넥트or의 명령에는 Azure CLI 2.41.0 이상이 필요합니다.

Azure Portal을 사용하여 관리 ID 할당

다음 단계에서는 다양한 웹 호스팅 서비스에 시스템 할당 관리 ID를 할당하는 방법을 보여 줍니다. 관리 ID는 이전에 설정한 앱 구성을 사용하여 다른 Azure 서비스에 안전하게 연결할 수 있습니다.

  1. Azure 앱 Service 인스턴스의 기본 개요 페이지에서 탐색 창에서 ID를 선택합니다.

  2. 시스템 할당 탭에서 상태 필드를 켜야 합니다. 시스템이 할당한 ID는 내부적으로 Azure에서 관리되며 관리 작업을 처리합니다. ID의 세부 정보 및 ID는 코드에서 공개되지 않습니다.

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

Azure CLI를 사용하여 Azure 호스팅 환경에서 관리 ID를 할당할 수도 있습니다.

다음 예제와 같이 az webapp identity assign 명령을 사용하여 Azure 앱 Service 인스턴스에 관리 ID를 할당할 수 있습니다.

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

관리 ID에 역할 할당

다음으로, MySQL 인스턴스에 액세스하기 위해 할당한 관리 ID에 권한을 부여합니다.

이러한 단계에서는 관리 ID에 대한 Microsoft Entra 사용자를 만들고 데이터베이스 $AZ_DATABASE_NAME 에 대한 모든 권한을 부여합니다. 필요에 맞게 데이터베이스 이름을 $AZ_DATABASE_NAME 변경할 수 있습니다.

먼저 관리자가 아닌 사용자를 만들기 위해 create_ad_user.sql이라는 SQL 스크립트를 만듭니다. 다음 콘텐츠를 추가하고 로컬에 저장합니다.

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

그런 다음, 다음 명령을 사용하여 SQL 스크립트를 실행하여 관리자가 아닌 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

이제 다음 명령을 사용하여 임시 SQL 스크립트 파일을 제거합니다.

rm create_ad_user.sql

앱 테스트

호스팅 환경에 앱을 배포하기 전에 애플리케이션이 관리 ID에 대해 만든 사용자를 사용하여 MySQL에 연결하기 때문에 코드를 한 번 더 변경해야 합니다.

관리 ID에 대해 만든 사용자를 사용하도록 코드를 업데이트합니다.

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

이러한 코드를 변경한 후 애플리케이션을 빌드하고 다시 배포할 수 있습니다. 그런 다음 브라우저에서 호스트된 애플리케이션으로 이동합니다. 앱이 MySQL 데이터베이스에 성공적으로 연결할 수 있어야 합니다. 역할 할당이 Azure 환경을 통해 전파되는 데 몇 분 정도 걸릴 수 있습니다. 이제 개발자가 애플리케이션 자체에서 비밀을 관리하지 않고도 애플리케이션이 로컬 및 프로덕션 환경 모두에서 실행되도록 구성되었습니다.

다음 단계

이 자습서에서는 애플리케이션을 암호 없는 연결로 마이그레이션하는 방법을 알아보았습니다.

다음 리소스를 참조하여 이 문서에서 설명하는 개념을 자세히 살펴볼 수 있습니다.