教學課程:使用 Microsoft Entra 應用程式建立 Microsoft Entra 使用者
適用於: Azure SQL 資料庫
本文說明如何設定服務主體,以便其可以在 Azure SQL 資料庫中建立 Microsoft Entra 使用者。 此功能可讓您以程式設計方式設定 Microsoft Entra 租用戶中使用者和應用程式的 Azure SQL 資源存取管理。
注意
Microsoft Entra ID 先前稱為 Azure Active Directory (Azure AD)。
如需 Azure SQL 的 Microsoft Entra 驗證詳細資訊,請參閱使用 Microsoft Entra 驗證一文。
在本教學課程中,您會了解如何:
- 將身分識別指派給邏輯伺服器
- 將目錄讀取者角色指派給伺服器身分識別
- 在 Microsoft Entra ID 中註冊應用程式
- 在 Azure SQL 資料庫中為該應用程式的服務主體建立資料庫使用者
- 使用服務主體建立 Microsoft Entra 資料庫使用者
必要條件
- 現有的 Azure SQL 資料庫部署。 我們假設您在此教學課程中有一個可運作的 SQL Database。
- SQL Database 所在租用戶中的 Microsoft Entra
Global Administrator
或Privileged Role Administrator
權限。 - Az.Sql PowerShell 模組的最新版本。
- Microsoft.Graph PowerShell 模組的最新版本。
將身分識別指派給邏輯伺服器
連線至 Azure,指定託管 SQL Database 的 Microsoft Entra 租用戶。 可以在 Azure 入口網站中 Microsoft Entra ID 資源的 [概觀] 頁面上找到租用戶 ID。 拷貝租用戶 ID,然後執行下列 PowerShell 命令:
- 使用您的租用戶 ID 取代
<TenantId>
。
Connect-AzAccount -Tenant <TenantId>
記錄
TenantId
,以供未來在此教學課程中使用。- 使用您的租用戶 ID 取代
產生系統指派的受控識別,並將其指派給 Azure 中的邏輯伺服器。 執行下列 PowerShell 命令:
- 將
<ResourceGroupName>
和<ServerName>
替換為您在 Set-AzSqlServer 命令中的資源。 如果您的伺服器名稱是myserver.database.windows.net
,使用myserver
取代<ServerName>
。
Set-AzSqlServer -ResourceGroupName <ResourceGroupName> -ServerName <ServerName> -AssignIdentity
- 將
檢查是否已成功指派伺服器身分識別。 執行下列 PowerShell 命令:
- 使用您的資源取代
<ResourceGroupName>
和<ServerName>
。 如果您的伺服器名稱是myserver.database.windows.net
,使用myserver
取代<ServerName>
。
$xyz = Get-AzSqlServer -ResourceGroupName <ResourceGroupName> -ServerName <ServerName> $xyz.identity
您的輸出應該會顯示
PrincipalId
、Type
和TenantId
。 指派的身分識別是PrincipalId
。- 使用您的資源取代
您也可以前往 Azure 入口網站來檢查身分識別。
- 在 Microsoft Entra ID 資源中,移至 [企業應用程式]。 輸入您的邏輯伺服器的名稱。 資源上的物件識別碼是主伺服器身分識別的 ID。
將伺服器身分識別新增至目錄讀取者角色
伺服器身分識別需要權限來查詢管理功能的 Microsoft Entra ID,包括建立 Microsoft Entra 使用者和登入以及執行群組擴充,以根據 Microsoft Entra 群組成員資格套用使用者權限。 如果撤銷查詢 Microsoft Entra ID 的伺服器身分識別權限,或刪除伺服器身分識別,Microsoft Entra 驗證將停止運作。
將 Microsoft Entra 查詢權限新增至目錄讀取者角色,或指派下列較低層級的 Microsoft Graph 權限,以將其指派給伺服器身分識別:
注意
此指令碼必須由 Microsoft Entra ID Global Administrator
或 Privileged Role Administrator
執行。
下列指令碼將 Microsoft Entra 目錄讀取者權限授與代表 Azure SQL 資料庫邏輯伺服器的身分識別。
- 使用稍早蒐集的
TenantId
取代<TenantId>
。 - 將
<ServerName>
替換為您自己的 SQL 邏輯伺服器名稱。 如果您的伺服器名稱是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 管理員。
在實際執行環境中,常見的管理做法是將目錄讀取者角色指派給 Microsoft Entra ID 中角色可指派的群組。 然後,群組擁有者可以將受控識別新增至群組。 這會維持最低權限準則,並略過全域系統管理員或特殊權限角色管理員的需求,個別將目錄讀取者角色授與每個 SQL 執行個體。 如需這項功能的詳細資訊,請參閱 Microsoft Entra ID 中適用於 Azure SQL 的目錄讀取者角色。
在 Microsoft Entra ID 中建立應用程式
註冊您的應用程式。 若要註冊應用程式,您至少需要 Microsoft Entra ID 應用程式開發人員角色。 如需有關指派角色的詳細資訊,請參閱在 Microsoft Entra ID 中指派使用者角色。
此教學課程使用兩個服務主體。 第一個服務主體 DBOwnerApp 用於在資料庫中建立其他使用者。 第二個服務主體 myapp 是 DBOwnerApp 在此教學課程稍後建立資料庫使用者的應用程式。
若要註冊應用程式:
在 Azure 入口網站中,依序選取 [Microsoft Entra ID]、[應用程式註冊]、[新建註冊]。>>
應用程式註冊建立之後,會產生及顯示應用程式 (用戶端) ID 值。 記錄此值,以供未來在此教學課程中使用。
為應用程式建立要登入的用戶端密碼。 依照上傳認證或建立登入祕密中所述操作。 記錄 DBOwnerApp 的用戶端密碼,以供此教學課程日後使用。
如需詳細資訊,請檢閱使用入口網站來建立可存取資源的 Microsoft Entra 應用程式和服務主體。
建立服務主體使用者
將新建立的服務主體 DBOwnerApp 新增為 SQL Database 中的使用者,並為其指派權限。
使用具有建立其他使用者的權限的 Microsoft Entra 身分識別,連線至您的 SQL Database。
重要
只有 Microsoft Entra 使用者可以在 Azure SQL 資料庫中建立其他 Microsoft Entra 使用者。 所有以 SQL 驗證為基礎的使用者,包括伺服器管理員,都無法建立 Microsoft Entra 使用者。 Microsoft Entra 管理員是唯一可以在 SQL Database 中初始建立其他 Microsoft Entra 使用者的使用者。 Microsoft Entra 管理員建立其他使用者之後,任何具有適當權限的 Microsoft Entra 使用者都可以建立其他 Microsoft Entra 使用者。
使用下列 T-SQL 命令,在 SQL Database 中建立使用者 DBOwnerApp:
CREATE USER [DBOwnerApp] FROM EXTERNAL PROVIDER GO
若要建立其他 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 USER
權限指派給 DBOwnerApp,如下列 T-SQL 範例所示:GRANT ALTER ANY USER TO [DBOwnerApp] GO
可以將 DBOwnerApp 設定為 Microsoft Entra 管理員。這可以使用 Azure 入口網站、PowerShell 或 Azure CLI 命令完成。 如需詳細資訊,請參閱設定 Microsoft Entra 管理員。
建立具有服務主體的使用者
透過下列指令碼,使用服務主體 DBOwnerApp 建立 Microsoft Entra 服務主體使用者 myapp:
- 使用稍早蒐集的
TenantId
取代<TenantId>
。 - 使用稍早蒐集的
ClientId
取代<ClientId>
。 - 使用稍早建立的用戶端密碼取代
<ClientSecret>
。 - 將
<ServerName>
替換為您自己的 SQL 邏輯伺服器名稱。 如果您的伺服器名稱是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 service principal authentication to Azure SQL 資料庫。 修改指令碼以執行 DDL 陳述式
CREATE USER [myapp] FROM EXTERNAL PROVIDER
。 您可以使用相同的指令碼,在資料庫中建立 Microsoft Entra 使用者或群組。- 使用稍早蒐集的
執行下列命令,以檢查使用者 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