チュートリアル: Microsoft Entra アプリケーションを使用して Microsoft Entra ユーザーを作成する

適用対象:Azure SQL Database

この記事では、Azure SQL データベースで Microsoft Entra ユーザーを作成できるようにサービス プリンシパルを構成する方法について説明します。 この機能により、Microsoft Entra テナント内のユーザーとアプリケーションの Azure SQL リソースへのアクセス管理をプログラムで構成できます。

Note

Microsoft Entra ID の、旧称は Azure Active Directory(Azure AD)です。

Azure SQL での Microsoft Entra の認証に関する詳細、「Microsoft Entra ID 認証を使用する」を参照してください。

このチュートリアルでは、次の作業を行う方法について説明します。

  • 論理サーバーに ID を割り当てる
  • サーバー ID にディレクトリ閲覧者ロールを割り当てる
  • アプリケーションを Microsoft Entra ID に登録します
  • Azure SQL データベースでそのアプリケーションのサービス プリンシパルのデータベース ユーザーを作成する
  • サービス プリンシパルを使用して Microsoft Entra データベース ユーザーを作成する

前提条件

  • 既存の Azure SQL Database のデプロイ。 このチュートリアルでは、SQL Database が既に稼動していることを前提としています。
  • SQL Database が存在するテナント内の Microsoft Entra Global Administrator または Privileged Role Administrator アクセス許可。
  • 最新バージョンの Az.Sql PowerShell モジュール。
  • 最新バージョンの Microsoft Graph PowerShell モジュール。

論理サーバーに ID を割り当てる

  1. SQL Database をホストする Microsoft Entra テナントを指定して、Azure に接続します。 テナント ID は、Azure portal 内の Microsoft Entra ID リソースの [概要] ページで確認できます。 テナント ID をコピーし、次の PowerShell コマンドを実行します。

    • <TenantId> は、実際のテナント ID に置き換えます。
    Connect-AzAccount -Tenant <TenantId>
    

    TenantId は記録しておいてください。後でこのチュートリアルの中で使用します。

  2. システム割り当てマネージド ID を生成し、Azure の論理サーバーに割り当てます。 次の PowerShell コマンドを実行します。

    • Set-AzSqlServer コマンドで <ResourceGroupName><ServerName> を実際のリソースに置き換えます。 実際のサーバー名が myserver.database.windows.net の場合、<ServerName>myserver に置き換えます。
    Set-AzSqlServer -ResourceGroupName <ResourceGroupName> -ServerName <ServerName> -AssignIdentity
    
  3. サーバー ID が正常に割り当てられたことを確認します。 次の PowerShell コマンドを実行します。

    • <ResourceGroupName><ServerName> は、実際の値に置き換えます。 実際のサーバー名が myserver.database.windows.net の場合、<ServerName>myserver に置き換えます。
    $xyz = Get-AzSqlServer -ResourceGroupName <ResourceGroupName> -ServerName <ServerName>
    $xyz.identity
    

    出力結果に PrincipalIdTypeTenantId が表示されます。 PrincipalId が、割り当てられた ID です。

  4. Azure portal にアクセスして ID を確認することもできます。

    • Microsoft Entra ID に移動し、[エンタープライズ アプリケーション] を選択します。 論理サーバーの名前を入力します。 リソースに表示されるオブジェクト ID は、プライマリ サーバー ID の ID です。

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

ディレクトリ閲覧者ロールにサーバー ID を追加する

サーバー ID には、Microsoft Entra のユーザーとログインの作成、および Microsoft Entra グループ メンバーシップに基づいてユーザーのアクセス許可を適用するためのグループ拡張の実行など、管理機能について Microsoft Entra ID を照会するためのアクセス許可が必要です。 Microsoft Entra ID を照会するためのサーバー ID のアクセス許可が取り消された場合、またはサーバー ID が削除された場合、Microsoft Entra 認証は動作を停止します。

Microsoft Entra クエリのアクセス許可をサーバー ID に割り当てるには、サーバー ID をディレクトリ閲覧者ロールに追加するか、次の下位レベルの Microsoft Graph アクセス許可を割り当てます。

Note

このスクリプトは、Microsoft Entra ID Global Administrator または Privileged Role Administrator で実行する必要があります。

次のスクリプトは、Azure SQL データベースの論理サーバーを表す ID に Microsoft Entra ディレクトリ閲覧者のアクセス許可を付与します。

  • <TenantId> は、先ほど確認した TenantId に置き換えます。
  • <ServerName> は、論理サーバーの名前に置き換えます。 実際のサーバー名が myserver.database.windows.net の場合、<ServerName>myserver に置き換えます。
# 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'."
}

Note

このスクリプトからの出力は、ID がディレクトリ閲覧者ロールに割り当てられているかどうかを示します。 アクセス許可が付与されたかどうかが定かでない場合は、スクリプトを再実行してください。

SQL Managed Instance にディレクトリ閲覧者ロールを割り当てる方法に関する同様のアプローチについては、「Microsoft Entra 管理者 (SQL Managed Instance) をプロビジョニングする」を参照してください。

運用環境では、ディレクトリ閲覧者ロールを Microsoft Entra ID のロール割り当て可能なグループに割り当てることが一般的な管理方法です。 その後、グループの所有者はマネージド ID をグループに追加できます。 これにより最小限の特権の原則を維持し、グローバル管理者または特権ロール管理者ディレクトリ閲覧者ロールをすべての SQL インスタンスに個別に付与する必要がなくなります。 この機能の詳細については、「Azure SQL の Microsoft Entra ID のディレクトリ閲覧者ロール」を参照してください。

Microsoft Entra ID でアプリケーションを作成する

アプリケーションを登録します。 アプリを登録するには、少なくとも Microsoft Entra ID アプリケーション開発者 ロールが必要です。 ロールの割り当て方法の詳細については、「Microsoft Entra ID に ユーザー ロールを割り当てる」をご覧ください。

このチュートリアルでは、2 つのサービス プリンシパルを使用します。 最初のサービス プリンシパル DBOwnerApp は、データベース内に他のユーザーを作成するために使用されます。 2 番目のサービス プリンシパル myapp は、このチュートリアルの後半で DBOwnerApp がデータベース ユーザーを作成するアプリケーションです。

アプリケーションを登録するには:

  1. Azure portal で、[Microsoft Entra ID>アプリの登録>新規登録] を選びます。

    Screenshot shows the Register an application page.

    アプリの登録が作成されると、アプリケーション (クライアント) ID値が生成され、表示されます。 この値は記録しておいてください。後でこのチュートリアルの中で使用します。

    Screenshot of the Azure portal that shows the App ID.

  2. サインイン用に、アプリケーションのクライアント シークレットを作成します。 「証明書をアップロードするか、サインイン用のシークレットを作成する」に従います。 このチュートリアルで今後使用するために、DBOwnerApp のクライアント シークレットを記録します。

詳細については、「リソースにアクセスできる Microsoft Entra アプリケーションとサービス プリンシパルをポータルで作成する」を確認してください。

サービス プリンシパル ユーザーを作成する

新しく作成したサービス プリンシパル DBOwnerApp を SQL Database のユーザーとして追加し、それにアクセス許可を割り当てます。

他のユーザーを作成するアクセス許可を持つ Microsoft Entra ID を使用して SQL Database に接続します。

重要

Azure SQL Database で他の Microsoft Entra ユーザーを作成できるのは、Microsoft Entra ユーザーだけです。 サーバー管理者を含む SQL 認証に基づくユーザーは、Microsoft Entra ユーザーを作成できません。 Microsoft Entra 管理者は、SQL Database で最初に他の Microsoft Entra ユーザーを作成できる唯一のユーザーです。 Microsoft Entra 管理者が他のユーザーを作成した後は、適切なアクセス許可を持つ Microsoft Entra ユーザーは、他の Microsoft Entra ユーザーを作成できます。

  1. 次の T-SQL コマンドを使用して、SQL Database にユーザー DBOwnerApp を作成します。

    CREATE USER [DBOwnerApp] FROM EXTERNAL PROVIDER
    GO
    
  2. 他の Microsoft Entra ユーザーを作成するには、少なくとも ALTER ANY USER SQL アクセス許可が必要です。 このアクセス許可は、db_owner のメンバーシップ、および Microsoft Entra 管理者としての割り当てを通じて継承されます。次の例では、データベース内に他の Microsoft Entra ユーザーを作成できるアクセス許可を DBOwnerApp に割り当てる 3 つの異なるオプションを示します。

    sp_addrolemember を使用して、DBOwnerAppdb_owner ロールに追加できます。

    EXEC sp_addrolemember 'db_owner', [DBOwnerApp]
    GO
    

    次のT-SQL サンプルのように、DBOwnerAppALTER ANY USER アクセス許可を割り当てることができます。

    GRANT ALTER ANY USER TO [DBOwnerApp]
    GO
    

    DBOwnerApp は Microsoft Entra 管理者として設定できます。これは、Azure portal、PowerShell、または Azure CLI コマンドを使用して行うことができます。 詳細については、「Microsoft Entra 管理者をプロビジョニングする (SQL Database)」を参照してください。

サービス プリンシパルを使用してユーザーを作成する

  1. 以下のスクリプトとサービス プリンシパル DBOwnerApp を使用して、Microsoft Entra サービス プリンシパル ユーザー myapp を作成します。

    • <TenantId> は、先ほど確認した TenantId に置き換えます。
    • <ClientId> は、先ほど確認した ClientId に置き換えます。
    • <ClientSecret> は、先ほど作成したクライアント シークレットに置き換えます。
    • <ServerName> は、論理サーバーの名前に置き換えます。 実際のサーバー名が myserver.database.windows.net の場合、<ServerName>myserver に置き換えます。
    • <database name> は、SQL Database の名前に置き換えます。
    # 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()
    

    または、Azure SQL データベースに対する Microsoft Entra サービス プリンシパル認証というコードを使用できます。 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
    

次のステップ