mssql-django를 사용한 Microsoft Entra 인증

이 문서에서는 mssql-django 백엔드를 사용하여 Django 애플리케이션용 Microsoft Entra 인증을 구성하는 방법을 설명합니다. Microsoft Entra 인증을 사용하면 애플리케이션 구성에 암호를 저장할 필요가 없습니다.

사전 요구 사항

  • Microsoft ODBC Driver 18 for SQL Server(권장). 이 문서의 모든 인증 모드는 SQL Server Microsoft ODBC Driver 18에서 지원됩니다. ActiveDirectoryInteractive는 드라이버 버전에 관계없이 Windows 전용입니다. ODBC 드라이버 17을 사용해야 하는 경우 모드별 최소 17.x 버전에 대한 ODBC 인증 참조 를 참조하세요.
  • 액세스 토큰 인증의 경우: pip install azure-identity.

인증 방법

Django 프로젝트의 settings.py 파일에서 DATABASES 설정을 추가하거나 편집하여 각 메서드를 구성합니다. 이 문서의 예제에서는 명확성을 위한 전체 DATABASES["default"] 블록을 보여 줍니다. 관련 키를 기존 구성에 복사합니다.

mssql-django는 다음 두 가지 방법으로 Microsoft Entra 인증을 지원합니다.

  • OPTIONS["extra_params"]을 통한 ODBC 드라이버 인증 백엔드는 이 문자열을 변경하지 않고 ODBC 연결 문자열에 추가하므로, 사용 가능한 Authentication= 값은 mssql-django 자체가 아니라 설치된 Microsoft ODBC Driver for SQL Server에서 가져옵니다.
  • TOKEN 설정을 통한 프로그래밍 방식 액세스 토큰 인증 백엔드는 TOKENSQL_COPT_SS_ACCESS_TOKEN로 ODBC 드라이버에 전달하며, 이로 인해 ODBC Authentication= 키워드를 우회합니다.

인증 방법 한눈에 보기

Method 다음을 사용하여 구성 적합한 대상
액세스 토큰 TOKEN 개발, 수명이 짧은 스크립트 또는 사용자 지정 토큰 새로 고침이 있는 앱
ActiveDirectoryMsi extra_params Azure 호스팅 프로덕션 앱(시스템 할당 및 사용자 할당 관리 ID)
ActiveDirectoryServicePrincipal USER, PASSWORD, extra_params 관리 ID를 사용할 수 없는 경우의 앱 등록
ActiveDirectoryIntegrated extra_params 도메인에 조인된 사용자 컨텍스트
ActiveDirectoryInteractive USER, extra_params 다단계 인증을 사용한 사용자 로그인(Windows)
ActiveDirectoryDefault extra_params ODBC 드라이버의 기본 Microsoft Entra 자격 증명 체인을 사용해야 하는 로컬 개발 및 앱
ActiveDirectoryPassword USER, PASSWORD, extra_params 최후의 수단으로만 사용하는 레거시 시나리오(더 이상 권장되지 않음)

Note

mssql-django 1.7.3 이상 버전에서는 설치된 Microsoft ODBC Driver for SQL Server가 해당 모드를 지원하는 경우 Authentication=ActiveDirectoryDefault부터 OPTIONS["extra_params"]까지 허용합니다. 토큰 획득 및 새로 고침 동작에 대한 명시적 제어가 필요한 경우 클래스와 함께 azure.identity.DefaultAzureCredential 패턴을 사용합니다.

Azure SQL ID 액세스 권한 부여

관리 ID 또는 서비스 주체 인증의 경우 데이터베이스 사용자를 만들고 애플리케이션에 필요한 역할만 부여합니다.

CREATE USER [<identity-name>] FOR EXTERNAL PROVIDER;

ALTER ROLE db_datareader ADD MEMBER [<identity-name>];
ALTER ROLE db_datawriter ADD MEMBER [<identity-name>];
ALTER ROLE db_ddladmin ADD MEMBER [<identity-name>];

db_ddladmin 고정 데이터베이스 역할은 애플리케이션이 마이그레이션을 실행하는 경우에만 필요합니다. 읽기 전용 워크로드의 경우 충분합니다 db_datareader .

Note

FROM EXTERNAL PROVIDER를 사용하려면 SQL Server가 Microsoft Graph를 호출하여 보안 주체 이름을 확인해야 합니다. 서버가 Microsoft Entra 전용 인증으로 구성되었거나 Graph에 연결할 수 없는 경우, 해당 구문은 Msg 33130(Principal '<name>' could not be found...)와 함께 실패합니다. 명시적 SID를 제공하여 사용자를 수동으로 만듭니다.

CREATE USER [<identity-name>] WITH SID = 0x<sid-hex>, TYPE = E;

관리형 ID 또는 서비스 프린시펄의 경우 SID는 개체 ID가 아니라 ID의 애플리케이션(클라이언트) ID에서 도출합니다. Azure SQL 서비스 주체 및 관리 ID에 애플리케이션 ID를 사용하고 일반 Entra 사용자에 대해서만 개체 ID를 사용합니다. 처음 세 개의 대시로 구분된 그룹은 바이트 단위로 역순으로 바꾸고 마지막 두 개는 그대로 유지하여 GUID를 변환합니다. 예를 들어 애플리케이션 ID 619a4449-b4aa-4383-a2a9-7c365106c5e7 는 SID 0x49449A61AAB48343A2A97C365106C5E7가 됩니다. PowerShell에서:

$b = ([Guid]"<app-id>").ToByteArray()
"0x" + (($b | ForEach-Object { $_.ToString('X2') }) -join '')

개체 ID를 잘못 사용하면 연결은 토큰 획득에 성공하지만, 토큰의 appid 클레임과 일치하는 데이터베이스 보안 주체가 없기 때문에 Azure SQL은 Login failed for user '<token-identified principal>'를 반환합니다.

VIEW ANY COLUMN MASTER KEY DEFINITION permission denied 오류가 표시되면 Always Encrypted 시나리오용 추가 액세스 권한을 해당 ID에 부여하세요.

GRANT VIEW ANY COLUMN MASTER KEY DEFINITION TO [<identity-name>];
GRANT VIEW ANY COLUMN ENCRYPTION KEY DEFINITION TO [<identity-name>];

관리 ID 인증(ActiveDirectoryMsi)

Django 앱이 Azure App Service, Azure Container Apps 또는 Azure Virtual Machines 같은 Azure 서비스에서 실행되는 경우 관리 ID를 사용합니다. 이 방법은 ODBC 드라이버가 토큰을 자동으로 획득하고 새로 고치기 때문에 프로덕션 환경에 권장됩니다.

시스템이 할당한 관리형 ID:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryMsi",
        },
    },
}

사용자가 할당한 관리형 ID:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "Authentication=ActiveDirectoryMsi;"
                "UID=<managed-identity-client-id-or-object-id>"
            ),
        },
    },
}

ActiveDirectoryMsi 는 SAMI(시스템 할당 관리 ID) 및 UAMI(사용자 할당 관리 ID) 모두에 대한 ODBC 모드입니다. UAMI의 경우 ODBC 드라이버는 UID 관리 ID를 식별해야 합니다. Azure App Service 또는 Azure Container Instance에 클라이언트 ID를 사용하고, 그렇지 않으면 개체 ID를 사용합니다. ODBC 드라이버에 직접 전달되기 때문에 UID 내부에 extra_paramsextra_params넣습니다.

관리 ID를 사용하는 경우 테스트 데이터베이스를 수동으로 만들고 단위 테스트를 실행할 때 전달 --keepdb 합니다.

서비스 주체 인증(ActiveDirectoryServicePrincipal)

앱이 사용자 컨텍스트 없이 실행되고 관리형 ID를 사용할 수 없는 경우 Microsoft Entra 앱 등록(서비스 주체)을 사용합니다.

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<application-client-id>",
        "PASSWORD": "<client-secret>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryServicePrincipal",
        },
    },
}

settings.py에 클라이언트 비밀을 하드코딩하지 마세요. 환경 변수 또는 Azure Key Vault 같은 비밀 관리자를 사용하여 런타임에 자격 증명을 제공합니다.

통합 인증(ActiveDirectoryIntegrated)

Django 프로세스가 도메인에 가입된 사용자 컨텍스트에서 실행되고 ODBC 드라이버가 해당 Windows 또는 Kerberos ID를 Microsoft Entra 인증에 사용하려는 경우 통합 인증을 사용합니다.

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryIntegrated",
        },
    },
}

ODBC 인증 참조는 페더레이션된 환경에 대한 ODBC Driver 17.6 이상 버전이 있는 Windows 및 Linux 또는 macOS에서 이 모드를 문서화합니다.

대화형 인증(ActiveDirectoryInteractive)

드라이버에서 자격 증명을 묻고 다단계 인증을 처리하도록 하려면 로컬 사용자 로그인에 대화형 인증을 사용합니다.

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<user@email.com>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryInteractive",
        },
    },
}

기본 ODBC 인증 참조 문서는 ActiveDirectoryInteractive Windows 전용입니다. 다른 플랫폼에서 사용하려는 경우 먼저 정확한 드라이버 버전으로 동작의 유효성을 검사합니다.

기본 자격 증명 체인 인증(ActiveDirectoryDefault)

ODBC 드라이버에서 기본 Microsoft Entra 자격 증명 체인을 적용하려는 경우 이 모드를 사용합니다.

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryDefault",
        },
    },
}

mssql-django 1.7.3 이상 버전은 이 모드를 ODBC 드라이버로 전달합니다. 자격 증명 원본 또는 토큰 새로 고침 동작을 명시적으로 제어해야 하는 경우 액세스 토큰 인증을 사용합니다.

액세스 토큰 인증(TOKEN)

Python 코드에서 Microsoft Entra 토큰 자체를 획득하려는 경우에 사용합니다TOKEN.

from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
token = credential.get_token("https://database.windows.net/.default").token

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "TOKEN": token,
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

이 경로는 DefaultAzureCredential, ManagedIdentityCredentialClientSecretCredential를 포함한 모든 Python 자격 증명 클래스와 함께 작동합니다.

인출된 settings.py 액세스 토큰은 프로세스 시작 시 한 번 평가되며 일반적으로 60~90분 후에 만료됩니다. Django 프로세스가 토큰 수명보다 오래 활성 상태로 유지되는 경우 애플리케이션 코드에서 토큰을 새로 고쳐야 합니다. 대부분의 장기 실행 프로덕션 앱의 경우 토큰을 자동으로 새로 고치는 ODBC 드라이버 모드(예: ActiveDirectoryMsi 또는 ActiveDirectoryServicePrincipal)를 사용합니다.

암호 인증(ActiveDirectoryPassword사용되지 않음)

Important

ActiveDirectoryPassword 인증 옵션(Microsoft Entra ID 암호 인증)은 Microsoft SQL 드라이버에서 더 이상 사용되지 않습니다. 이 고위험 인증 흐름은 필수 Microsoft Entra MFA(다단계 인증)와 호환되지 않으며 MFA가 적용되는 테넌트에서는 작동하지 않을 수 있습니다. 다른 Microsoft Entra 인증 방법으로 마이그레이션할 계획입니다.

Microsoft Entra ID 암호 인증은 OAuth 2.0 ROPC(리소스 소유자 암호 자격 증명) 부여를 기반으로 하며, 이를 통해 애플리케이션은 암호를 직접 처리하여 사용자에 로그인할 수 있습니다.

Microsoft MFA와 호환되지 않으므로 ROPC 흐름을 사용하지 않는 것이 좋습니다. 대부분의 시나리오에서는 보다 안전한 대안을 사용할 수 있으며 권장됩니다. 이 흐름은 애플리케이션에 대한 높은 수준의 신뢰가 필요하며 다른 흐름에 없는 위험을 수반합니다. 더 안전한 흐름이 실행 가능하지 않은 경우에만 이 흐름을 사용합니다. Microsoft는 악의적인 공격으로부터 사용자를 보호하기 위해 이 고위험 인증 흐름에서 벗어나고 있습니다. 자세한 내용은 Azure에 대한 필수 다단계 인증 계획을 참조하세요.

사용자가 로그인할 때 로그인한 사용자 및 조건부 액세스 정책에 대한 감사 내역 특성이 적용되도록 ActiveDirectoryInteractive 또는 ActiveDirectoryIntegrated 인증을 사용합니다.

무인 서비스 간 시나리오의 경우 Microsoft Entra 서비스 계정 지침을 따르세요:

  • 애플리케이션이 Azure 인프라에서 실행되는 경우 ActiveDirectoryMSI(또는 일부 드라이버의 ActiveDirectoryManagedIdentity)를 사용합니다. 관리형 ID는 암호 및 인증서를 유지 관리하고 교체하는 데 따르는 오버헤드를 제거합니다.
  • 관리 ID를 사용할 수 없는 경우(예: 애플리케이션이 Azure 외부에서 실행됨) ActiveDirectoryServicePrincipal을 사용합니다. 드라이버에서 지원하는 경우 클라이언트 암호보다 클라이언트 인증서를 선호합니다. 인증서를 사용하면 프라이빗 키가 클라이언트에 유지되고 서명된 어설션만 Microsoft Entra 전송되어 클라이언트를 인증합니다. 키가 하드웨어(예: TPM 또는 HSM)에 저장되거나 보고할 수 없는 것으로 표시된 경우 클라이언트 암호가 할 수 있는 방식으로 문자열로 복사할 수 없습니다.
  • Microsoft Entra 사용자 계정을 서비스 계정으로 사용하지 마세요.

레거시 시나리오에 사용해야 하는 경우 명시적으로 구성합니다.

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<user@email.com>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryPassword",
        },
    },
}