SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

Try using External REST Endpoints Integration (Preview) of SQL Database

leave a comment

Azure SQL Database External REST Endpoints Integration Public Preview でアナウンスがありましたが、SQL Database で、SQL から REST API をコールすることができる sp_invoke_external_rest_endpoint というストアドプロシージャがプレビューで提供されました。

SQL 単体で、REST をコールして情報を取得することができる機能となります。

呼び出しができるエンドポイントについては、許可されているエンドポイント に記載されている次のエンドポイントに限定され、これ以外のエンドポイントについては、サポートされるエンドポイントでラップして呼び出す必要があります。

image

本機能の使用方法のサンプルについては Azure SQL DB sp_invoke_external_rest_endpoint samples が提供されているのですが、この中で触れられていない Microsoft Graph を使用して、本機能を確認してみました。

SQL Database から Graph REST API を呼び出すための準備

SQL Database から Graph REST API を呼び出すために、SQL Database の論理サーバーの Managed Identity から API を呼び出すための権限を付与しておきます。(呼び出し方法についてはいくつかのパターンを採用できると思いますが今回は Managed Identity を使用しています)

権限の付与ですが、今回は チュートリアル: セキュリティで保護された .NET アプリからアプリとして Microsoft Graph にアクセスする の方法を使用しています。

このチュートリアルでは、Azure AD PowerShell が使用されており、本投稿でもそれを利用していますが、Azure Active Directory の PowerShell モジュール / MSOnline / AzureAD PowerShell から Graph PowerShell SDK への移行について 1_概要 等でアナウンスされているとおり、今後は Graph PowerShell SDK への移行が推奨されていますので、2023/3/31 以降は Graph PowerShell を利用したほうが良いかと思います。

また、PowerShell 7 で AzureAD PowerShell を実行しようとすると powershell login error のエラーになるかもしれませんので、Windows PowerShell で実行したほうが簡単かと思います。

SQL Database の Managed Identity に Grapu REST API からユーザーの読み取りを実行する場合は次のようなスクリプトを実行します。

$TenantID="<Tenant ID>"
$objectId = "<Managed Identity object id>"


Connect-AzureAD -TenantId $TenantID

$PermissionName = "User.Read.All"
$GraphServicePrincipal = Get-AzureADServicePrincipal -SearchString "Microsoft Graph" | Select-Object -first 1

$AppRole = $GraphServicePrincipal.AppRoles | `
Where-Object {$_.Value -eq $PermissionName -and $_.AllowedMemberTypes -contains "Application"}

New-AzureAdServiceAppRoleAssignment -ObjectId $objectId -PrincipalId $objectId -ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id

# 削除する場合は以下を実行
$srAssignment = Get-AzureADServiceAppRoleAssignment -ObjectId $GraphServicePrincipal.ObjectId | ? PrincipalId -eq $objectId
Remove-AzureADServiceAppRoleAssignment -ObjectId $GraphServicePrincipal.ObjectId -AppRoleAssignmentId $srAssignment.ObjectId

 

このようなスクリプトを実行すると Microsoft Graph に対して、Managed Identity が読み取りのアクセスが付与されます。

AAD のポータルで設定状況を確認する場合は、次の情報になるのではないでしょうか。

  • [エンタープライズアプリケーション] -> [すべてのアプリケーション] -> [アプリケーションの種類のフィルターを削除] -> [Microsoft Graph] で、アプリケーション ID [00000003-0000-0000-c000-000000000000] のアプリケーションを選択し、[ユーザーとグループ]
  • [エンタープライズアプリケーション] -> [すべてのアプリケーション] -> [アプリケーションの種類のフィルターを削除] -> [SQL Database の論理サーバー名を入力] -> [アクセス許可]

Managed Identity に対して次のような権限が付与されていれば、事前の準備は完了です。

image

 

SQL Database から Graph API を呼び出す

それでは実際に呼び出してみたいと思います。事前に CREATE MASTER KEY でデータベースマスターキーの作成は完了しているという前提でのクエリです。

IF EXISTS (SELECT * FROM sys.database_scoped_credentials WHERE name = 'https://graph.microsoft.com/v1.0/users')
BEGIN
    DROP DATABASE SCOPED CREDENTIAL [https://graph.microsoft.com/v1.0/users];
END

CREATE DATABASE SCOPED CREDENTIAL [https://graph.microsoft.com/v1.0/users] 
WITH 
    IDENTITY = 'Managed Identity'
    , SECRET = '{"resourceid":"https://graph.microsoft.com/"}';
GO


DECLARE @response nvarchar(max)
EXEC sp_invoke_external_rest_endpoint 
    @url = 'https://graph.microsoft.com/v1.0/users'
    , @method='GET'
    , @response = @response OUTPUT
    , @credential = [https://graph.microsoft.com/v1.0/users]

IF (SELECT JSON_VALUE(@response, '$.response.status.http.code')) <> 200
BEGIN
    SELECT [key],[value] FROM OPENJSON(@response, '$.response.headers')
    UNION ALL
    SELECT [key],[value] FROM OPENJSON(@response, '$.result.error')
END
ELSE
BEGIN
    SELECT 
        JSON_VALUE(value, '$.displayName') AS displayName ,
        JSON_VALUE(value, '$.userPrincipalName') AS userPrincipalName 
    
    FROM OPENJSON(@response, '$.result.value')
END

 

軽く試した感じでは、このようなクエリを実行することで、Graph API を SQL で呼び出し、ユーザーの一覧を取得することができました。

実際に使用している自分のテナントの情報なので、白塗りが多くて何をとっているのかわからないですが、ユーザー情報の取得が行えています。

image

どのような処理を SQL Database 側で実装すると効率が良いのかは悩ましいところではありますが、面白い機能なのではないでしょうか。

Share

Written by Masayuki.Ozawa

12月 7th, 2022 at 9:10 pm

Posted in SQL Database

Tagged with

Leave a Reply