教學課程:使用 Microsoft Entra 應用程式建立 Microsoft Entra 使用者

適用於:Azure SQL Database

本文說明如何設定服務主體,以便在 Azure SQL 資料庫 中建立 Microsoft Entra 使用者。 此功能可讓您以程式設計方式設定 Microsoft Entra 租使用者中使用者和應用程式的 Azure SQL 資源存取管理。

注意

Microsoft Entra 標識符 先前稱為 Azure Active Directory (Azure AD)。

如需 Azure SQL 的 Microsoft Entra 驗證詳細資訊,請參閱使用 Microsoft Entra 驗證一文

在本教學課程中,您會了解如何:

  • 將身分識別指派給邏輯伺服器
  • 將目錄讀取者角色指派給伺服器身分識別
  • 在 Microsoft Entra 識別碼中註冊應用程式
  • 在 Azure SQL 資料庫 中為該應用程式的服務主體建立資料庫使用者
  • 使用服務主體建立 Microsoft Entra 資料庫使用者

必要條件

  • 現有的 Azure SQL Database 部署。 我們假設您在此教學課程中有一個可運作的 SQL Database。
  • SQL 資料庫所在租使用者中的 Microsoft Entra Global AdministratorPrivileged Role Administrator 許可權。
  • 最新版的 Az.Sql PowerShell 模組。
  • 最新版的 Microsoft.Graph PowerShell 模組。

將身分識別指派給邏輯伺服器

  1. 連線 至 Azure,指定裝載 SQL 資料庫的 Microsoft Entra 租使用者。 您可以在 Azure 入口網站Microsoft Entra ID 資源的 [概觀] 頁面上找到租用戶識別碼。 複製租用戶 標識碼 ,然後執行下列 PowerShell 命令:

    • 使用您的租用戶識別碼取代 <TenantId>
    Connect-AzAccount -Tenant <TenantId>
    

    記錄 TenantId,以供未來在此教學課程中使用。

  2. 產生系統指派的受控識別,並將其指派給 Azure 中的邏輯伺服器。 執行下列 PowerShell 命令:

    • 將和 <ServerName> 取代<ResourceGroupName>為 Set-AzSqlServer 命令中的資源。 如果您的伺服器名稱是 myserver.database.windows.net,使用 myserver 取代 <ServerName>
    Set-AzSqlServer -ResourceGroupName <ResourceGroupName> -ServerName <ServerName> -AssignIdentity
    
  3. 檢查是否已成功指派伺服器身分識別。 執行下列 PowerShell 命令:

    • 使用您的資源取代 <ResourceGroupName><ServerName>。 如果您的伺服器名稱是 myserver.database.windows.net,使用 myserver 取代 <ServerName>
    $xyz = Get-AzSqlServer -ResourceGroupName <ResourceGroupName> -ServerName <ServerName>
    $xyz.identity
    

    您的輸出應該會顯示 PrincipalIdTypeTenantId。 指派的身分識別是 PrincipalId

  4. 您也可以前往 Azure 入口網站來檢查身分識別。

    • Microsoft Entra 識別符 資源中,移至 [企業應用程式]。 輸入邏輯伺服器的名稱。 出現在資源上的物件識別碼是主伺服器識別的標識碼。

    Screenshot shows where to find the Object ID for an enterprise application.

將伺服器身分識別新增至目錄讀取者角色

伺服器身分識別需要許可權來查詢系統管理功能的 Microsoft Entra ID,包括建立 Microsoft Entra 使用者和登入,以及執行群組擴充,以根據其 Microsoft Entra 群組成員資格來套用用戶權力。 如果撤銷查詢 Microsoft Entra 識別碼的伺服器身分識別許可權,或刪除伺服器身分識別,Microsoft Entra 驗證就會停止運作。

將 Microsoft Entra 查詢許可權新增至目錄讀取者角色,或指派下列較低層級的 Microsoft Graph 許可權,將它指派給伺服器身分識別:

注意

此腳本必須由 Microsoft Entra ID Global Administrator 或 執行 Privileged Role Administrator

下列腳本會將 Microsoft Entra Directory Readers 許可權授與代表 Azure SQL 資料庫 邏輯伺服器的身分識別。

  • 使用稍早蒐集的 TenantId 取代 <TenantId>
  • 將取代 <ServerName> 為您的邏輯伺服器名稱。 如果您的伺服器名稱是 myserver.database.windows.net,使用 myserver 取代 <ServerName>
# This script grants "Directory Readers" permission to a service principal representing a logical server for Azure SQL Database
# It can be executed only by a user who is a member of the **Global Administrator** or **Privileged Role Administrator** role.
# To check if the "Directory Readers" role was granted, re-execute this script

Import-Module Microsoft.Graph.Authentication
$ServerIdentityName = "<ServerName>"    # Enter your logical server name
$TenantId = "<TenantId>"                # Enter your tenant ID

Connect-MgGraph -TenantId "<TenantId>" -Scopes "RoleManagement.ReadWrite.Directory,Application.Read.All"

# Get Microsoft Entra "Directory Readers" role and create if it doesn't exist
$roleName = "Directory Readers"
$role = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'"
if ($role -eq $null) {
    # Instantiate an instance of the role template
    $roleTemplate = Get-MgDirectoryRoleTemplate -Filter "DisplayName eq '$roleName'"
    New-MgDirectoryRoleTemplate -RoleTemplateId $roleTemplate.Id
    $role = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'"
}

# Get service principal for server
$roleMember = Get-MgServicePrincipal -Filter "DisplayName eq '$ServerIdentityName'"
$roleMember.Count
if ($roleMember -eq $null) {
    Write-Output "Error: No service principal with name '$($ServerIdentityName)' found, make sure that ServerIdentityName parameter was entered correctly."
    exit
}
if (-not ($roleMember.Count -eq 1)) {
    Write-Output "Error: Multiple service principals with name '$($ServerIdentityName)'"
    Write-Output $roleMember | Format-List DisplayName, Id, AppId
    exit
}

# Check if service principal is already member of Directory Readers role
$isDirReader = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id -Filter "Id eq '$($roleMember.Id)'"

if ($isDirReader -eq $null) {
    # Add principal to Directory Readers role
    Write-Output "Adding service principal '$($ServerIdentityName)' to 'Directory Readers' role'..."
    $body = @{
        "@odata.id"= "https://graph.microsoft.com/v1.0/directoryObjects/{$($roleMember.Id)}"
    }
    New-MgDirectoryRoleMemberByRef -DirectoryRoleId $role.Id -BodyParameter $body
    Write-Output "'$($ServerIdentityName)' service principal added to 'Directory Readers' role'."
} else {
    Write-Output "Service principal '$($ServerIdentityName)' is already member of 'Directory Readers' role'."
}

注意

此文稿的輸出會指出識別是否已指派給 目錄讀取者 角色。 如果您不確定是否已授與權限,則可重新執行指令碼。

如需如何為 SQL 受管理執行個體 指派目錄讀取者角色的類似方法,請參閱布建 Microsoft Entra 系統管理員(SQL 受管理執行個體)。

在生產環境中,常見的管理做法是將目錄讀取者角色指派給 Microsoft Entra ID 中可指派的角色群組。 然後,群組擁有者可以將受控識別新增至群組。 這會維持最低許可權的原則,並略過全域 管理員 istrator 或 Privileged Role 管理員 istrator 的需求,以個別將目錄讀取者角色授與每個 SQL 實例。 如需此功能的詳細資訊,請參閱 Azure SQL 的 Microsoft Entra ID 中的目錄讀取者角色。

在 Microsoft Entra 識別碼中建立應用程式

註冊您的應用程式。 若要註冊應用程式,您至少需要 Microsoft Entra ID 應用程式開發人員 角色。 如需指派角色的詳細資訊,請參閱 在 Microsoft Entra ID 中指派使用者角色。

本教學課程使用兩個服務主體。 第一個服務主體 DBOwnerApp 是用來在資料庫中建立其他使用者。 第二個服務主體 myapp 是 DBOwnerApp 在本教學課程稍後建立資料庫用戶的應用程式

若要註冊您的應用程式:

  1. 在 Azure 入口網站 中,選取 [Microsoft Entra ID> 應用程式註冊>[新增註冊]。

    Screenshot shows the Register an application page.

    建立應用程式註冊之後, 就會產生並顯示 [應用程式] [用戶端] 識別符 值。 記錄此值以供本教學課程日後使用。

    Screenshot of the Azure portal that shows the App ID.

  2. 為應用程式建立要登入的客戶端密碼。 請遵循 上傳憑證,或建立用於登入的秘密。 記錄 DBOwnerApp客戶端密碼,以供本教學課程日後使用。

如需詳細資訊,請參閱 使用入口網站建立可存取資源的 Microsoft Entra 應用程式和服務主體。

建立服務主體使用者

將新建立的服務主體 DBOwnerApp 新增為 SQL 資料庫 中的使用者,並將許可權指派給它。

使用具有建立其他用戶許可權的 Microsoft Entra 身分識別,連線 至您的 SQL 資料庫。

重要

只有 Microsoft Entra 用戶可以在 Azure SQL 資料庫 中建立其他 Microsoft Entra 使用者。 任何以 SQL 驗證為基礎的使用者,包括伺服器管理員,都無法建立 Microsoft Entra 使用者。 Microsoft Entra 系統管理員是唯一可以在 SQL 資料庫 中建立其他 Microsoft Entra 使用者的使用者。 在 Microsoft Entra 系統管理員建立其他用戶之後,任何具有適當許可權的 Microsoft Entra 使用者都可以建立其他 Microsoft Entra 使用者。

  1. 使用下列 T-SQL 命令,在 SQL 資料庫 中建立使用者 DBOwnerApp

    CREATE USER [DBOwnerApp] FROM EXTERNAL PROVIDER
    GO
    
  2. 若要建立其他 Microsoft Entra 使用者,至少 ALTER ANY USER 需要 SQL 許可權。 此許可權也會透過 中的 db_owner成員資格繼承,以及透過指派作為 Microsoft Entra 系統管理員。下列範例示範三種不同的選項,將許可權指派給 DBOwnerApp ,以允許它在資料庫中建立其他 Microsoft Entra 使用者。

    您可以使用下列sp_addrolemember,將 DBOwnerApp 新增db_owner角色

    EXEC sp_addrolemember 'db_owner', [DBOwnerApp]
    GO
    

    您可以將許可權指派 ALTER ANY USERDBOwnerApp ,例如下列 T-SQL 範例:

    GRANT ALTER ANY USER TO [DBOwnerApp]
    GO
    

    您可以將 DBOwnerApp 設定為 Microsoft Entra 系統管理員。這可以使用 Azure 入口網站、PowerShell 或 Azure CLI 命令來完成。 如需詳細資訊,請參閱布建 Microsoft Entra admin (SQL 資料庫)。

使用服務主體建立使用者

  1. 使用下列腳本,使用服務主體 DBOwnerApp 建立 Microsoft Entra 服務主體使用者 myapp

    • 使用稍早蒐集的 TenantId 取代 <TenantId>
    • 使用稍早蒐集的 ClientId 取代 <ClientId>
    • 使用稍早建立的用戶端密碼取代 <ClientSecret>
    • 將取代 <ServerName> 為您的邏輯伺服器名稱。 如果您的伺服器名稱是 myserver.database.windows.net,使用 myserver 取代 <ServerName>
    • 使用您的 SQL Database 名稱取代 <database name>
    # PowerShell script for creating a new SQL user called myapp using application DBOwnerApp with secret
    # DBOwnerApp is an admin for the server
    
    # Download latest  MSAL  - https://www.powershellgallery.com/packages/MSAL.PS
    Import-Module MSAL.PS
    
    $tenantId = "<TenantId>"   # Microsoft Entra tenant ID where DBOwnerApp resides
    $clientId = "<ClientId>"   # Application (client) ID recorded earlier for DBOwnerApp
    $clientSecret = "<ClientSecret>"   # Client secret for DBOwnerApp 
    $scopes = "https://database.windows.net/.default" # The endpoint
    
    $result = Get-MsalToken -RedirectUri $uri -ClientId $clientId -ClientSecret (ConvertTo-SecureString $clientSecret -AsPlainText -Force) -TenantId $tenantId -Scopes $scopes
    
    $Tok = $result.AccessToken
    #Write-host "token"
    $Tok
    
    $SQLServerName = "<ServerName>"    # Logical server name 
    $DatabaseName = "<database name>"   # Azure SQL database name
    
    Write-Host "Create SQL connection string"
    $conn = New-Object System.Data.SqlClient.SQLConnection 
    $conn.ConnectionString = "Data Source=$SQLServerName.database.windows.net;Initial Catalog=$DatabaseName;Connect Timeout=30"
    $conn.AccessToken = $Tok
    
    Write-host "Connect to database and execute SQL script"
    $conn.Open() 
    $ddlstmt = 'CREATE USER [myapp] FROM EXTERNAL PROVIDER;'
    Write-host " "
    Write-host "SQL DDL command"
    $ddlstmt
    $command = New-Object -TypeName System.Data.SqlClient.SqlCommand($ddlstmt, $conn)       
    
    Write-host "results"
    $command.ExecuteNonQuery()
    $conn.Close()
    

    或者,您可以使用下列程序代碼:Microsoft Entra 服務主體驗證至 Azure SQL 資料庫。 變更文稿以執行 DDL 語句 CREATE USER [myapp] FROM EXTERNAL PROVIDER。 相同的腳本可用來在資料庫中建立 Microsoft Entra 使用者或群組。

  2. 執行下列命令,以檢查使用者 myapp 是否存在於資料庫中:

    SELECT name, type, type_desc, CAST(CAST(sid as varbinary(16)) as uniqueidentifier) as appId
    FROM sys.database_principals
    WHERE name = 'myapp'
    GO
    

    您應該會看到如下的輸出:

    name	type	type_desc	appId
    myapp	E	EXTERNAL_USER	6d228f48-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    

下一步