자습서: 서비스 커넥터를 통해 데이터베이스 서비스에 암호 없는 연결 만들기

암호 없는 연결은 관리 ID를 사용하여 Azure 서비스에 액세스합니다. 이 방법을 사용하면 관리 ID에 대한 비밀을 수동으로 추적하고 관리할 필요가 없습니다. 이러한 작업은 Azure에서 내부적으로 안전하게 처리됩니다.

서비스 커넥터를 사용하면 Azure Spring Apps, Azure App Service 및 Azure Container Apps와 같은 앱 호스팅 서비스에서 관리 ID를 사용할 수 있습니다. 또한 서비스 커넥터는 관리 ID를 허용하도록 Azure Database for PostgreSQL, Azure Database for MySQL 및 Azure SQL Database와 같은 데이터베이스 서비스를 구성합니다.

이 자습서에서는 Azure CLI를 사용하여 다음 작업을 완료합니다.

  • Azure CLI를 사용하여 초기 환경을 확인합니다.
  • 서비스 커넥터를 사용하여 암호 없는 연결을 만듭니다.
  • 서비스 커넥터에서 생성된 환경 변수 또는 구성을 사용하여 데이터베이스 서비스에 액세스합니다.

필수 조건

환경 설정

어카운트

az login을 통해 Azure CLI로 로그인합니다. Azure Cloud Shell을 사용 중이거나 이미 로그인한 경우 az account show로 인증된 계정을 확인합니다.

서비스 커넥터 암호 없는 확장 설치

Azure CLI용 서비스 커넥터 암호 없는 확장을 설치합니다.

az extension add --name serviceconnector-passwordless --upgrade

암호 없는 연결 만들기

다음으로 Azure App Service를 예로 사용하여 관리 ID를 통해 연결을 만듭니다.

사용하는 경우:

참고 항목

Azure Portal을 사용하는 경우 Azure App Service, Azure Spring Apps 또는 Azure Container Apps서비스 커넥터 블레이드로 이동하고 만들기를 선택하여 연결을 만듭니다. Azure Portal은 자동으로 명령을 작성하고 Cloud Shell에서 명령 실행을 트리거합니다.

다음 Azure CLI 명령은 --client-type 매개 변수를 사용합니다. az webapp connection create postgres-flexible -h를 실행하여 지원되는 클라이언트 형식을 가져오고 애플리케이션과 일치하는 클라이언트 형식을 선택합니다.

az webapp connection create postgres-flexible \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $POSTGRESQL_HOST \
    --database $DATABASE_NAME \
    --user-identity client-id=XX subs-id=XX \
    --client-type java

Azure Database for MySQL - 유연한 서버에는 Microsoft Entra 인증을 사용하도록 설정하기 위해 사용자가 할당한 관리 ID가 필요합니다. 자세한 내용은 Azure Database for MySQL - 유연한 서버에 대한 Microsoft Entra 인증 설정을 참조하세요. 다음 명령을 사용하여 사용자가 할당한 관리 ID를 만들 수 있습니다.

USER_IDENTITY_NAME=<YOUR_USER_ASSIGNED_MANAGEMED_IDENTITY_NAME>
IDENTITY_RESOURCE_ID=$(az identity create \
    --name $USER_IDENTITY_NAME \
    --resource-group $RESOURCE_GROUP \
    --query id \
    --output tsv)

Important

사용자가 할당한 ID를 만든 후 전역 관리자 또는 권한 있는 역할 관리자에게 요청하여 이 ID에 대해 다음 권한 부여를 요청합니다.

  • User.Read.All
  • GroupMember.Read.All
  • Application.Read.All

자세한 내용은 Active Directory 인증권한 섹션을 참조하세요.

그런 다음, 서비스 커넥터를 사용하여 시스템이 할당한 관리 ID로 앱을 MySQL 데이터베이스에 연결합니다.

다음 Azure CLI 명령은 --client-type 매개 변수를 사용합니다. az webapp connection create mysql-flexible -h를 실행하여 지원되는 클라이언트 형식을 가져오고 애플리케이션과 일치하는 클라이언트 형식을 선택합니다.

az webapp connection create mysql-flexible \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $MYSQL_HOST \
    --database $DATABASE_NAME \
    --user-identity client-id=XX subs-id=XX mysql-identity-id=$IDENTITY_RESOURCE_ID \
    --client-type java

다음 Azure CLI 명령은 --client-type 매개 변수를 사용합니다. az webapp connection create sql -h를 실행하여 지원되는 클라이언트 형식을 가져오고 애플리케이션과 일치하는 클라이언트 형식을 선택합니다.

az webapp connection create sql \
    --resource-group $RESOURCE_GROUP \
    --name $APPSERVICE_NAME \
    --target-resource-group $RESOURCE_GROUP \
    --server $SQL_HOST \
    --database $DATABASE_NAME \
    --user-identity client-id=XX subs-id=XX \
    --client-type dotnet

이 서비스 커넥터 명령은 백그라운드에서 다음 작업을 완료합니다.

  • 시스템이 할당한 관리 ID를 사용하도록 설정하거나 Azure App Service/Azure Spring Apps/Azure Container Apps에서 호스트하는 앱 $APPSERVICE_NAME에 대한 사용자 ID를 할당합니다.
  • Microsoft Entra 관리자를 현재 로그인한 사용자로 설정합니다.
  • 시스템이 할당한 관리 ID, 사용자가 할당한 관리 ID 또는 서비스 주체에 대한 데이터베이스 사용자를 추가합니다. 이 사용자에게 데이터베이스 $DATABASE_NAME의 모든 권한을 부여합니다. 사용자 이름은 이전 명령 출력의 연결 문자열에서 찾을 수 있습니다.
  • AZURE_MYSQL_CONNECTIONSTRING, AZURE_POSTGRESQL_CONNECTIONSTRING 또는 AZURE_SQL_CONNECTIONSTRING이라는 구성을 데이터베이스 유형에 기반한 Azure 리소스로 설정합니다.
    • App Service의 경우 구성은 앱 설정 블레이드에서 설정됩니다.
    • Spring Apps의 경우 애플리케이션이 시작될 때 구성이 설정됩니다.
    • Container Apps의 경우 구성이 환경 변수로 설정됩니다. Azure Portal의 서비스 커넥터 블레이드에서 모든 구성 및 해당 값을 가져올 수 있습니다.

Microsoft Entra 인증을 사용하여 데이터베이스에 연결

연결을 만든 후 애플리케이션에서 연결 문자열을 사용하여 Microsoft Entra 인증을 통해 데이터베이스에 연결할 수 있습니다. 예를 들어 다음 솔루션을 사용하여 Microsoft Entra 인증을 통해 데이터베이스에 연결할 수 있습니다.

.NET의 경우 암호 없는 연결을 지원하는 플러그 인 또는 라이브러리가 없습니다. Azure.Identity와 같은 클라이언트 라이브러리를 사용하여 관리 ID 또는 서비스 주체에 대한 액세스 토큰을 가져올 수 있습니다. 그런 다음 액세스 토큰을 암호로 사용하여 데이터베이스에 연결할 수 있습니다. 아래 코드를 사용하는 경우 사용하려는 인증 유형에 대한 코드 조각 부분의 주석 처리를 제거합니다.

using Azure.Identity;
using Azure.Core;
using Npgsql;

// Uncomment the following lines according to the authentication type.
// For system-assigned identity.
// var sqlServerTokenProvider = new DefaultAzureCredential();

// For user-assigned identity.
// var sqlServerTokenProvider = new DefaultAzureCredential(
//     new DefaultAzureCredentialOptions
//     {
//         ManagedIdentityClientId = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CLIENTID");
//     }
// );

// For service principal.
// var tenantId = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_TENANTID");
// var clientId = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CLIENTID");
// var clientSecret = Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CLIENTSECRET");
// var sqlServerTokenProvider = new ClientSecretCredential(tenantId, clientId, clientSecret);

// Acquire the access token. 
AccessToken accessToken = await sqlServerTokenProvider.GetTokenAsync(
    new TokenRequestContext(scopes: new string[]
    {
        "https://ossrdbms-aad.database.windows.net/.default"
    }));

// Combine the token with the connection string from the environment variables provided by Service Connector.
string connectionString =
    $"{Environment.GetEnvironmentVariable("AZURE_POSTGRESQL_CONNECTIONSTRING")};Password={accessToken.Token}";

// Establish the connection.
using (var connection = new NpgsqlConnection(connectionString))
{
    Console.WriteLine("Opening connection using access token...");
    connection.Open();
}

다음으로, 서비스 커넥터를 사용하기 전에 PostgreSQL 유연한 서버에서 테이블 및 시퀀스를 만든 경우 소유자로 연결하고 서비스 커넥터에서 만든 <aad-username>에 사용 권한을 부여해야 합니다. 서비스 커넥터에 설정한 연결 문자열 또는 구성의 사용자 이름은 aad_<connection name>과 같습니다. Azure Portal을 사용하는 경우 Service Type 열 옆에 있는 확장 단추를 선택하고 값을 가져옵니다. Azure CLI를 사용하는 경우 CLI 명령 출력에서 configurations를 확인합니다.

그런 다음 쿼리를 실행하여 사용 권한을 부여합니다.

az extension add --name rdbms-connect

az postgres flexible-server execute -n <postgres-name> -u <owner-username> -p "<owner-password>" -d <database-name> --querytext "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"<aad-username>\";GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO \"<aad username>\";"

<owner-username><owner-password>는 다른 사용자에게 사용 권한을 부여할 수 있는 기존 테이블의 소유자입니다. <aad-username>은 서비스 커넥터에서 만든 사용자입니다. 실제 값으로 바꿉니다.

다음 명령을 사용하여 결과의 유효성을 검사합니다.

az postgres flexible-server execute -n <postgres-name> -u <owner-username> -p "<owner-password>" -d <database-name> --querytext "SELECT distinct(table_name) FROM information_schema.table_privileges WHERE grantee='<aad-username>' AND table_schema='public';" --output table

.NET의 경우 암호 없는 연결을 지원하는 플러그 인 또는 라이브러리가 없습니다. Azure.Identity와 같은 클라이언트 라이브러리를 사용하여 관리 ID 또는 서비스 주체에 대한 액세스 토큰을 가져올 수 있습니다. 그런 다음 액세스 토큰을 암호로 사용하여 데이터베이스에 연결할 수 있습니다. 아래 코드를 사용하는 경우 사용하려는 인증 유형에 대한 코드 조각 부분의 주석 처리를 제거합니다.

using Azure.Core;
using Azure.Identity;
using MySqlConnector;

// Uncomment the following lines according to the authentication type.
// For system-assigned managed identity.
// var credential = new DefaultAzureCredential();

// For user-assigned managed identity.
// var credential = new DefaultAzureCredential(
//     new DefaultAzureCredentialOptions
//     {
//         ManagedIdentityClientId = Environment.GetEnvironmentVariable("AZURE_MYSQL_CLIENTID");
//     });

// For service principal.
// var tenantId = Environment.GetEnvironmentVariable("AZURE_MYSQL_TENANTID");
// var clientId = Environment.GetEnvironmentVariable("AZURE_MYSQL_CLIENTID");
// var clientSecret = Environment.GetEnvironmentVariable("AZURE_MYSQL_CLIENTSECRET");
// var credential = new ClientSecretCredential(tenantId, clientId, clientSecret);

var tokenRequestContext = new TokenRequestContext(
    new[] { "https://ossrdbms-aad.database.windows.net/.default" });
AccessToken accessToken = await credential.GetTokenAsync(tokenRequestContext);
// Open a connection to the MySQL server using the access token.
string connectionString =
    $"{Environment.GetEnvironmentVariable("AZURE_MYSQL_CONNECTIONSTRING")};Password={accessToken.Token}";

using var connection = new MySqlConnection(connectionString);
Console.WriteLine("Opening connection using access token...");
await connection.OpenAsync();

// do something

코드 샘플에 대한 자세한 내용은 관리 ID를 사용하여 비밀 없이 App Service에서 Azure 데이터베이스에 연결을 참조하세요.

  1. 종속성을 설치합니다.

    dotnet add package Microsoft.Data.SqlClient
    
  2. 서비스 커넥터에서 추가한 환경 변수에서 Azure SQL Database 연결 문자열을 가져옵니다.

    using Microsoft.Data.SqlClient;
    
    string connectionString = 
        Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTIONSTRING")!;
    
    using var connection = new SqlConnection(connectionString);
    connection.Open();
    

    자세한 내용은 Active Directory 관리 ID 인증 사용을 참조하세요.

자세한 내용은 Microsoft SQL Server로의 클라이언트 프로그래밍 홈페이지를 참조하세요.

Azure App Service에 애플리케이션 배포

마지막으로 Azure 호스팅 서비스에 애플리케이션을 배포합니다. 해당 원본 서비스는 관리 ID를 사용하여 Azure의 대상 데이터베이스에 연결할 수 있습니다.

Azure App Service의 경우 az webapp deploy 명령을 통해 애플리케이션 코드를 배포할 수 있습니다. 자세한 내용은 빠른 시작: ASP.NET 웹앱 배포를 참조하세요.

그런 다음 로그를 확인하거나 애플리케이션을 호출하여 Azure 데이터베이스에 성공적으로 연결할 수 있는지 확인할 수 있습니다.

문제 해결

Permission

사용 권한 관련 오류가 발생하는 경우 az account show 명령을 사용하여 Azure CLI 로그인 사용자를 확인합니다. 올바른 계정으로 로그인해야 합니다. 다음으로, 서비스 커넥터를 사용하여 암호 없는 연결을 만드는 데 필요한 다음 권한이 있는지 확인합니다.

Permission 연산
Microsoft.DBforPostgreSQL/flexibleServers/read 데이터베이스 서버의 정보를 가져오는 데 필요
Microsoft.DBforPostgreSQL/flexibleServers/write 데이터베이스 서버에 대해 Microsoft Entra 인증을 사용하도록 설정하는 데 필요
Microsoft.DBforPostgreSQL/flexibleServers/firewallRules/write 로컬 IP 주소가 차단된 경우 방화벽 규칙을 만드는 데 필요
Microsoft.DBforPostgreSQL/flexibleServers/firewallRules/delete 보안 문제를 방지하기 위해 서비스 커넥터에서 만든 방화벽 규칙을 되돌리는 데 필요
Microsoft.DBforPostgreSQL/flexibleServers/administrators/read Azure CLI 로그인 사용자가 데이터베이스 서버 Microsoft Entra 관리자인지 확인하는 데 필요
Microsoft.DBforPostgreSQL/flexibleServers/administrators/write Azure CLI 로그인 사용자를 데이터베이스 서버 Microsoft Entra 관리자로 추가하는 데 필요
Permission 연산
Microsoft.DBforMySQL/flexibleServers/read 데이터베이스 서버의 정보를 가져오는 데 필요
Microsoft.DBforMySQL/flexibleServers/write 제공된 사용자가 할당한 관리 ID를 데이터베이스 서버에 추가하는 데 필요
Microsoft.DBforMySQL/flexibleServers/firewallRules/write 로컬 IP 주소가 차단된 경우 방화벽 규칙을 만드는 데 필요
Microsoft.DBforMySQL/flexibleServers/firewallRules/delete 보안 문제를 방지하기 위해 서비스 커넥터에서 만든 방화벽 규칙을 되돌리는 데 필요
Microsoft.DBforMySQL/flexibleServers/administrators/read Azure CLI 로그인 사용자가 데이터베이스 서버 Microsoft Entra 관리자인지 확인하는 데 필요
Microsoft.DBforMySQL/flexibleServers/administrators/write Azure CLI 로그인 사용자를 데이터베이스 서버 Microsoft Entra 관리자로 추가하는 데 필요
Permission 연산
Microsoft.Sql/servers/read 데이터베이스 서버의 정보를 가져오는 데 필요
Microsoft.Sql/servers/firewallRules/write 로컬 IP 주소가 차단된 경우 방화벽 규칙을 만드는 데 필요
Microsoft.Sql/servers/firewallRules/delete 보안 문제를 방지하기 위해 서비스 커넥터에서 만든 방화벽 규칙을 되돌리는 데 필요
Microsoft.Sql/servers/administrators/read Azure CLI 로그인 사용자가 데이터베이스 서버 Microsoft Entra 관리자인지 확인하는 데 필요
Microsoft.Sql/servers/administrators/write Azure CLI 로그인 사용자를 데이터베이스 서버 Microsoft Entra 관리자로 추가하는 데 필요

경우에 따라 권한이 필요하지 않습니다. 예를 들어 Azure CLI 인증 사용자가 이미 SQL 서버의 Active Directory 관리자인 경우 Microsoft.Sql/servers/administrators/write 권한이 필요하지 않습니다.

Microsoft Entra ID

ERROR: AADSTS530003: Your device is required to be managed to access this resource. 오류가 발생하면 IT 부서에 이 디바이스를 Microsoft Entra ID에 조인하는 방법에 대해 지원을 요청하세요. 자세한 내용은 Microsoft Entra 조인 디바이스를 참조하세요.

서비스 커넥터는 계정의 정보와 호스팅 서비스의 관리 ID를 가져오려면 Microsoft Entra ID에 액세스해야 합니다. 다음 명령을 사용하여 디바이스가 Microsoft Entra ID에 액세스할 수 있는지 확인할 수 있습니다.

az ad signed-in-user show

대화형으로 로그인하지 않은 경우 오류와 Interactive authentication is needed가 표시될 수도 있습니다. 오류를 해결하려면 az login 명령을 사용하여 로그인합니다.

네트워크 연결

데이터베이스 서버가 Virtual Network에 있는 경우 Azure CLI 명령을 실행하는 환경이 Virtual Network의 서버에 액세스할 수 있는지 확인합니다.

데이터베이스 서버가 Virtual Network에 있는 경우 Azure CLI 명령을 실행하는 환경이 Virtual Network의 서버에 액세스할 수 있는지 확인합니다.

데이터베이스 서버에서 공용 액세스를 허용하지 않는 경우 Azure CLI 명령을 실행하는 환경이 프라이빗 엔드포인트를 통해 서버에 액세스할 수 있는지 확인합니다.

다음 단계

서비스 커넥터 및 암호 없는 연결에 대한 자세한 내용은 다음 리소스를 참조하세요.