Azure App ServiceからAzure SQL DatabaseにマネージドIDを利用して接続する

こんにちは。この記事では、Azure App Service上にデプロイしたアプリから、マネージドIDを利用してAzure SQL Databaseに接続する方法をご紹介します。(公式Docを見ながら実装してみた結果のメモ)

それではまいります。

そもそもマネージドIDって?

こちらにまとめとります。

[実装] まずはマネージドIDを使わずSQL Databaseに接続するアプリの作成

まずは、マネージドIDを使わない通常の接続文字列を用いた接続ができるアプリを準備したいと思います。

Azure App Service側の操作

Azure App Serviceリソースの作成

はじめにアプリのデプロイ先として、Azure App Serviceリソースを作成します。

.NET6ランタイムで作成する点以外は、特に今回の実験には影響しないので何でもよいです。

リソースの作成が完了したら、URLにアクセスして、デフォルトの画面が表示されることだけ確認しておきます。

App Serviceの前準備はこれだけ。

Azure SQL Database側の操作

Azure SQL Databaseリソースの作成

続けてSQL Database側の準備です。こちらも規定値で作成してしまって大丈夫です。

ファイアウォール設定の変更

ファイアウォールの設定で「Azureサービスおよびリソースにこのサーバへのアクセスを許可する」を「はい」に+クライアントIPの追加(データ投入・デバッグ用)を行っておきます。

Azure SQL Databaseへのテストデータ投入

続けて、SQL Databaseにテストデータを投入します。超適当なテーブルとデータですが、クエリエディタから以下コマンドを実行します。

CREATE TABLE Users (
    UserId INT IDENTITY PRIMARY KEY,
    UserName NVARCHAR(128) NOT NULL,
);

INSERT INTO Users(UserName) VALUES ('SampleUser1');
INSERT INTO Users(UserName) VALUES ('SampleUser2');

SELECT * FROM Users;

サンプルアプリケーションの作成

こちらを参考にしました。

https://docs.microsoft.com/ja-jp/azure/azure-sql/database/connect-query-dotnet-core

次はアプリケーションです。Visual StudioでASP.NET Core Brazorテンプレートを指定してアプリを作成します。

.NET6で作成する点だけ注意。

System.Data.SqlClientパッケージを追加します。

Index.cshtmlとIndex.cshtml.csをそれぞれ以下内容に書き換えます。ここでポイントなのが、この接続方式では接続文字列情報にユーザIDとパスワードを含んでいるという点です。後のManaged IDでこのリスクを回避できます。

//Index.cshtml
@page
@model IndexModel
@using System.Data.SqlClient;
@using System.Diagnostics;
@{
    //テーブルの内容を表示する領域を追加
    List<IndexModel.Users>resultSet = new List<IndexModel.Users>();
    try 
    { 
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();

        builder.ConnectionString="<SQL Databaseの接続文字列>";

        using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
        {

            connection.Open();       

            String sql = "SELECT * FROM Users";

            using (SqlCommand command = new SqlCommand(sql, connection))
            {
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        IndexModel.Users details = new IndexModel.Users();
                        details.UserId = reader[0].ToString();
                        details.UserName = reader[1].ToString();
                        resultSet.Add(details);

                    }
                }
            }                    
        }
    }
    catch (SqlException e)
    {
        Debug.WriteLine(e.ToString());
    }

    ViewBag.Title = "Home page";
    ViewBag.Body = resultSet;
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>

    //テーブルの内容を表示する領域を追加
    <table border="1" width="90%">
        <tr>
            <th>UserId</th>
            <th>UserName</th>
        </tr>
    @foreach(var v in ViewBag.Body)
    {
        <tr>
            <td>@v.UserId</td>
            <td>@v.UserName</td>
        </tr>
    }
    </table>
</div>
//Index.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace WebApps_SQLDB_ManagedId.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }

        //データ取得結果を格納する箱の構造を定義
        public class Users
        {
            public string? UserId { get; set; }
            public string? UserName { get; set; }
        }


        public void OnGet()
        {

        }
    }
}

ここで、先ほど作成したWebAppsにデプロイします。

デプロイ完了後、アプリを開くと・・・

SQL Databaseに接続してデータベースの情報を取得できていることが確認できました!

[実装] マネージドIDを使ってSQL Databaseに接続するよう構成を変更

それではいよいよ本題の、マネージドIDを使った接続に切り替えていきます。

ここからは、以下の公式ドキュメントを参考にしました。

Azure SQL Databaseと接続する.NETアプリの作成

https://docs.microsoft.com/ja-jp/azure/app-service/tutorial-connect-msi-sql-database?tabs=windowsclient%2Cef%2Cdotnet

[App Service] マネージドIDの有効化

まず、App ServiceでマネージドIDを有効化します。

App Service > ID > システム割り当て済みタブから、システム割り当てマネージドIDを有効化します。

「はい」を選択。

すると、Azure AD上にサービスプリンパルが作成されて、マネージドIDが利用できるようになりました。

[SQL Database] Azure Active Directory認証の有効化

次にSQL DatabaseでAzure Active Directory認証を有効化します。

Azure Active Directory > 管理者の設定から、管理者とするAzure ADユーザ(今回は自分)を追加します。(この手順がなんのために必要なのかちょっとわからなかったですが(ローカルでのデバッグ用?)、分かったら追記します)

[SQL Database] マネージドID用のDBユーザの作成

データベースにマネージドID用のユーザを作成し、必要な権限を付与します。(今回はチュートリアルの通り付与しています)

データベースリソースのクエリエディタから実行すればOKです。

CREATE USER [<identity-name>] FROM 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>];
GO

これでAzureリソース側の設定は完了です。

[アプリ] 接続文字列の変更

最後に、アプリケーションコードの変更です。

ここで、データベース接続クライアントを、先ほどまで利用していたSystem.Data.SqlClientからMicrosoft.Data.SqlClientに変更します。

#マネージドIDを利用した接続の場合、接続文字列に”Authentication”プロパティが入るのですが、System.Data.SqlClientだとこのプロパティを含むとエラーになってしまうため、チュートリアルに従ってMicrosoft.Data.SqlClientを利用します。

コードは以下の通り変更します。接続文字列のところを見ていただきたいのですが、先ほどのユーザ名、パスワードを含んだものと比べると、認証方式を指定するAuthenticationプロパティが増えたのと、ユーザ名・パスワード情報は含まれなくなりました。

// index.cshtml

// System.Data.SqlClientの代わりにこちら以下を利用します。
@using Microsoft.Data.SqlClient;

・・・
// 接続文字列を以下のように変更します
builder.ConnectionString="Server=tcp:XXXXX.database.windows.net,1433;Authentication=Active Directory Default; Database=XXXXX;";

この状態でApp Serviceにデプロイしてコードが実行されると、App Serviceのアプリ自体がサービスプリンシプルとなり、そのID(マネージドID)を利用してSQL Databaseへのログインがなされることになります。

実際にデプロイしてページを開くと・・・引き続きデータベースからデータが取得できていることが確認できました!

以上、マネージドIDを利用してApp ServiceからSQL Databaseに接続する手順でした。

参考になりましたら幸いです。

おしまい

この記事を気に入っていただけたらシェアをお願いします!

コメントを残す

メールアドレスが公開されることはありません。

ABOUT US
Yuu113
初めまして。ゆうたろうと申します。 兵庫県出身、東京でシステムエンジニアをしております。現在は主にデータ分析、機械学習を活用してビジネスモデリングに取り組んでいます。 日々学んだことや経験したことを整理していきたいと思い、ブログを始めました。旅行、カメラ、IT技術、江戸文化が大好きですので、これらについても記事にしていきたいと思っています。