Microsoft.Data.SqlClient の接続文字列

Microsoft.Data.SqlClient の接続文字列は、セミコロンで区切られた keyword=value のペアのリストです。 SqlConnectionかSqlConnectionStringBuilderにパスしてください:

Server=tcp:sql.example.com,1433;Database=Orders;Integrated Security=true;Encrypt=Strict

接続文字列は、次の 4 つの質問に答えるものです:

  1. アプリケーションはどのサーバーとデータベースを使っていますか?
  2. アプリケーションはどのアイデンティティで動作しますか?
  3. クライアントはどのようにしてサーバー証明書を検証するのでしょうか?
  4. ワークロードに必要な接続動作は何でしょうか?

この記事では、その選択とドライバーがテキストを読む際に使うルールについて説明します。 各キーワード、その同義語、およびデフォルト設定については、接続オプションを参照してください。 コード内で接続文字列を作成・変更するには 、接続文字列ビルダーを参照してください。

認証パターンを選択する

実施する展開に適したパターンを使用してください。 <server> などのプレースホルダーを、それぞれの値に置き換えます。

環境 パターン 接続文字列
ドメインまたはローカルWindowsアイデンティティを持つWindows上のSQL Server Windows 統合認証 Server=<server>;Database=<database>;Integrated Security=true;Encrypt=true
AzureでホストされたアプリケーションとAzure SQL接続 Microsoft Entra ID のマネージド ID Server=tcp:<server>.database.windows.net,1433;Database=<database>;Authentication=Active Directory Managed Identity;Encrypt=Strict
Azure SQL に接続する開発者ワークステーション Microsoft Entra ID デフォルト認証チェーン Server=tcp:<server>.database.windows.net,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict
開発者ワークステーションがMicrosoft FabricのSQLデータベースに接続 Microsoft Entra ID デフォルト認証チェーン Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict
Azure SQL に接続する対話型デスクトップ ツール Microsoft Entra ID インタラクティブ認証 Server=tcp:<server>.database.windows.net,1433;Database=<database>;Authentication=Active Directory Interactive;Encrypt=Strict
SQL認証を必要とする環境 シークレットストアからのユーザー名とパスワード Server=<server>;Database=<database>;User ID=<user>;Password=<password>;Encrypt=true

Windows 統合認証では、プロセスの ID として接続が行われます。 デスクトップやコンソールアプリケーションの場合、通常はサインインしているユーザーです。 ウェブアプリケーションやWindowsサービスの場合は、アプリケーションプールやサービスアカウントです。 なりすましは、ID 自体を変えてしまう可能性があります。 アプリケーションが実際に使っているアイデンティティにログインとデータベース権限を付与します。

これら3つのWindows統合認証形式は同等です:

Server=sql.example.com;Database=Orders;Integrated Security=true;Encrypt=true
Server=sql.example.com;Database=Orders;Integrated Security=SSPI;Encrypt=true
Server=sql.example.com;Database=Orders;Trusted_Connection=yes;Encrypt=true

文字列がIntegrated Security=trueを設定し、User IDとPasswordも設定した場合、ドライバーはWindows 認証を使い、ユーザー名とパスワードを無視します。

Microsoft.Data.SqlClient 7.0以降のバージョンでは、ドライバーが提供するMicrosoft Entra ID認証方法に対してバージョンマッチドMicrosoft.Data.SqlClient.Extensions.Azureパッケージが必要です。 アプリケーションコードがアクセストークンやアクセストークンコールバックを提供する場合は、そのパッケージは必要ありません。

受け入れられた Authentication 値については 、認証オプションをご覧ください。 認証にはデータベースユーザー、権限、サーバー上のアイデンティティ設定も必要です。 設定手順については、Microsoft Entra ID認証およびSQL Server認証を参照してください。

サーバーとデータベースを指定する

Server そして Database は最も読みやすいキーワード名です。 ビルダーは、それらを正規形である Data Source と Initial Catalog として記述します。 4つの名前はすべて接続文字列(接続文字列)で動作します。

Serverを以下のいずれかの形式に設定してください:

Form Example Use
ホスト名 Server=sql.example.com ポート1433のデフォルトインスタンスです。
ホスト名とポート Server=tcp:sql.example.com,1433 特定のTCPポートです。 ポートはコロンではなくコンマで区切ってください。
名前付きインスタンス Server=sql.example.com\SALES 名前付きのインスタンス。 ドライバーは、UDPポート1434上のSQL Server Browserサービスにポートを問い合わせます。
ローカルサーバー Server=(local) または Server=. ローカルコンピュータのデフォルトインスタンスです。
LocalDB Server=(localdb)\MSSQLLocalDB SQL Server Express LocalDBを Windows で使用します。 Encrypt=Mandatory を設定しても接続は暗号化されず、Encrypt=Strict は失敗します。
名前付きパイプ Server=np:\\sql.example.com\pipe\sql\query Windowsの名前付きパイプ接続です。

運用環境では、tcp:、完全修飾ホスト名、明示的なポート番号を使用してください。 IPアドレスではなく、サーバー証明書と一致するDNS名を使用してください。なぜなら、証明書検証は接続文字列内のサーバー名と証明書の名前を比較するからです。

SQL認証とuser@servernameフォームのユーザー名でAzure SQL Databaseに接続する場合、servername部分はServerのサーバーと一致しなければなりません。

可用性グループのリスナーまたはフェールオーバー クラスターのインスタンスについては、接続オプションの Multi Subnet Failover も確認してください。

暗号化と証明書検証の設定

Encrypt キーワードは、いずれの場合も以下の値を受け付けます:

価値 ビルダーの値 Meaning
Strict Strict TDS 8.0を使用しています。 ログイン前に接続を暗号化し、常にサーバー証明書の有効性を確認します。
Mandatory、true、yes True 接続を暗号化します。 この値が既定値です。
Optional、false、no False サーバーが暗号化を要求する場合にのみ、接続全体を暗号化します。 サーバーが暗号化をサポートしているが、それを必須としていない場合、ログイン パケットのみを暗号化します。

サーバーが TDS 8.0 をサポートしており、かつ、クライアントが検証できる証明書を備えている場合は、Strict を使用します。 Azure SQL DatabaseおよびMicrosoft FabricのSQLデータベースはこれをサポートしています。 LocalDB 接続は、Mandatory を使用しても暗号化されず、Strict は失敗します。

Encrypt値とTrust Server Certificate値は以下のように組み合わさります。

暗号化する サーバー証明書を信頼する Result
Optional false サーバーが暗号化を必要とする場合、接続全体が暗号化され、サーバー証明書が検証されなければなりません。 そうしないと、接続に失敗します。 サーバーが暗号化をサポートしているが、それを必須としていない場合、ログインパケットのみが暗号化され、接続が AccessToken または AccessTokenCallback を使用していない限り、ドライバーはサーバー証明書の検証を行いません。 サーバーが暗号化をサポートしていない場合、何も暗号化されません。
Optional true サーバーが暗号化を必要とする場合、接続全体が暗号化されます。 サーバーが暗号化をサポートしているが必須でない場合、暗号化されるのはログインパケットのみです。 ドライバーはサーバー証明書を検証しません。
Mandatory false 暗号化は、サーバー証明書の検証が成功した場合にのみ行われます。 そうしないと、接続に失敗します。
Mandatory true 暗号化は常に行われますが、ドライバーはサーバー証明書の検証を行いません。
Strict 無視 暗号化は常に行われ、サーバー証明書は検証されなければなりません。 そうしないと、接続に失敗します。

本番環境での接続エラーを修正するために Trust Server Certificate=true を設定しないでください。 通信経路を暗号化しますが、サーバーの身元を確認するわけではありません。 信頼できる証明書が存在しない開発環境に限定してください。

Data Source内のサーバー名が証明書と一致しない場合は、Host Name In Certificateを証明書の名前に設定してください。 SqlClientはサーバー名と一致しない時だけチェックし、証明書のピン留めもしません。 特定の証明書を1つだけ受け入れるには、「Server Certificate」にPEM、DER、またはCERファイルのパスを設定します。

Server=tcp:sql.example.com,1433;Encrypt=Strict;Host Name In Certificate=sqlhost.example.com
Server=tcp:sql.example.com,1433;Encrypt=Strict;Server Certificate=C:\certificates\server.cer

検証ルールの詳細については、暗号化と証明書の検証を参照してください。

接続プーリングを使用する

プーリングはデフォルトでオンになっています。 SqlConnection を開くと、ドライバーはその接続に一致するプールから物理的な接続を取得します。 接続を閉じたり解放したりすると、物理的な接続は閉じられるのではなく、プールに戻されます。 プールされたオープンはネットワーク接続、TLSハンドシェイク、ログインをスキップします。

次の規則に従います。

  • 接続が必要になる直前に接続を開き、処理が終わり次第、using または await using を使用してその接続を解放してください。 廃棄されていない接続はチェックアウトのままで、プールが尽きることもあります。

  • 起動時に一度接続文字列を作成し、それを再利用してください。 プールキーには接続文字列の正確なテキストが含まれているため、異なるキーワードの順序、同義語、またはリクエストIDやユーザー名などのリクエストごとの値が別個のプールを形成します。 ビルダーは一つの正準形を出力します。 詳細については、「Keep one canonical 接続文字列」を参照してください。

  • 統合認証のもとで各Windowsアイデンティティ、各SqlCredentialインスタンス、各AccessToken値ごとに別々のプールが用意されることを期待してください。 接続のたびに AccessToken を設定する代わりに、ドライバーが提供する Authentication メソッド、または再利用された AccessTokenCallback を使用してください。

  • Max Pool Size (デフォルトは 100) を増加させる前に、破棄されていない接続を探してください。 プール内のすべての接続が使用中の場合、 Open は最大 Connect Timeout まで待ち、その後 InvalidOperationExceptionを投げます:

    Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.
    
  • すべてのプールのサーバー容量を計画しましょう。 .NETフレームワーク上の各プロセス、または各アプリケーションドメインは独自のプールを持っています。 サーバーへの接続数は、各プロセス内のプール数とアプリケーション インスタンスの数に Max Pool Size を掛けた値に達する可能性があります。

  • プーリングの問題を回避するために、Pooling=false を設定しないでください。 オープンが行われるたびに、完全なログイン処理が実行されます。

長くアイドル状態のプール接続を閉じるには、「 接続アイドル時間の制限」を参照してください。 プールキー、サイズ設定、クリアリング、トランザクションについては、SQL Server接続プーリングを参照してください。

接続設定とコマンド設定を別々に

接続文字列は接続の確立とセッションの動作を制御します。 コマンドは1つのSQL操作を制御します。

要件 構成対象
接続を確立するか、プールから取得するまでの許容時間 Connect Timeout キーワード
接続上のコマンドのデフォルトタイムアウト Command Timeout キーワード
1つのコマンドのタイムアウト CommandTimeout
電話主からのキャンセル CancellationToken が非同期メソッドに渡されました
接続を開くかコマンドを実行するためのリトライポリシー 構成可能な再試行ロジック (SqlConnection または SqlCommand 上)

タイムアウトが長くなるのは再試行ロジックではありません。 タイムアウトは待機時間の制限です。 再試行とは、再度の試行を開始することを指し、その試行は範囲が限定されており、安全に繰り返せるものでなければなりません。

アプリケーションの ID を報告する

Application Name サーバーが APP_NAME()を通じて報告する名前を設定します。 デプロイされた各ワークロードに対して1つの安定名を使いましょう。 アプリケーション用に接続を開くフレームワークやツールも、接続文字列キーワードを持たないこのRegisteredApplicationプロパティを通じて自己報告できます。 詳細については、アプリケーション ID の報告を参照してください。

接続ストリングを安全に作る

コードが値を追加・変更するときには SqlConnectionStringBuilder を使いましょう。 信頼できないテキストを接続文字列に結合しないでください。なぜなら、そのテキストのセミコロンがキーワードを追加または置き換えることがあるからです。 このビルダーは、値の妥当性を検証し、同義語を正規のキーワードにマッピングし、各値を引用符で囲むことで、その値にキーワードが追加されないようにします。 たとえば、接続文字列ビルダーを参照します。

コード外での接続情報の保存

アプリケーションの設定システムから接続文字列を読み込みます。 .NETアプリケーションは一般的に環境変数、ローカル開発のためのユーザーシークレット、Azure App Configuration、Azure Key Vaultを使用します。

次の規則に従います。

  • パスワード、クライアントシークレット、アクセストークン、本番接続文字列はコミットしないでください。
  • 接続文字列にパスワードを指定する必要のない認証方式を優先してください。
  • 設定ソースへのアクセスを制限してください。
  • 保存されたシークレットをローテーションし、それらをキャッシュしているアプリケーションを再起動または再読み込みします。
  • ログ、例外、トレース、テレメトリに接続文字列を書かないでください。
  • デフォルト値の Persist Security Info=false のままにしておくと、開かれた接続がその ConnectionString プロパティを通じてパスワードを漏洩することはありません。

.NET 設定プロバイダーについては、「.NET 内の構成」を参照してください。 その他のコントロールについては、接続情報の保護をご覧ください。

構文解析ルール

ドライバーは以下のルールを適用します:

  • キーワードでは大文字と小文字は区別されません。 DATABASE、 Database、 database は同じキーワードです。
  • 多くのキーワードには同義語があります。 Server と Data Source は同じ値を設定します。 Connectionオプションの記事には、各キーワードの同義語が記載されています。
  • キーワードが複数回出現した場合、最後の値が優先されます。 同義語は同じキーワードとしてカウントされます。
  • ドライバーはキーワードや引用符なしの値の周りのスペースを無視します。
  • 末尾のセミコロンは任意です。
  • ドライバーが認識できないキーワードがあると、メッセージ Keyword not supported とともに ArgumentException が発生します。

値はキーワードによって大文字と小文字を区別することがあります。 パスワードでは大文字と小文字が区別されます。 Encrypt=STRICT と Encrypt=strict は同じです。

このプログラムは、ビルダーがどのようにキーワードを正規化し、重複を解決し、特殊文字を引用するかを示します。 .NET Framework タブでは、C# 7.3 が使用されています。 サンプルを実行するプロジェクトを作成するには、「 プロジェクトを作成」をご覧ください。

using Microsoft.Data.SqlClient;

// Synonyms and keyword case are normalized to canonical keywords.
var parsed = new SqlConnectionStringBuilder(
    "server=tcp:sql.example.com,1433;DATABASE=Orders;uid=app_user;encrypt=yes;timeout=30");
Console.WriteLine(parsed.ConnectionString);

// When a keyword repeats, the last value wins.
var duplicate = new SqlConnectionStringBuilder(
    "Server=sql.example.com;Database=Orders;Database=Archive");
Console.WriteLine($"InitialCatalog: {duplicate.InitialCatalog}");

// The builder quotes values that contain delimiters.
var quoted = new SqlConnectionStringBuilder
{
    DataSource = "sql.example.com",
    UserID = "app_user",
    Password = "a;b'c\"d",
};
Console.WriteLine(quoted.ConnectionString);
Console.WriteLine($"Round trip: {new SqlConnectionStringBuilder(quoted.ConnectionString).Password == quoted.Password}");

出力は次のとおりです。

Data Source=tcp:sql.example.com,1433;Initial Catalog=Orders;User ID=app_user;Connect Timeout=30;Encrypt=True
InitialCatalog: Archive
Data Source=sql.example.com;User ID=app_user;Password="a;b'c""d"
Round trip: True

1 行目には、各同義語が標準キーワードに置き換えられたものが示されています。server は Data Source に、DATABASE は Initial Catalog に、uid は User ID に、そして timeout は Connect Timeout に置き換えられています。

引用値

値にセミコロンが含まれている場合、先頭または末尾にスペースがある場合、あるいは先頭または末尾に引用符がある場合は、その値を二重引用符 (") または単一引用符 (') で囲んでください。 引用符で囲まれた値の中では、その引用符を 2 つ続けて記述してください。

価値 接続文字列形式
a;b Password="a;b"
abc' Password="abc'"
say "hi" Password='say "hi"'
a;b'c"d Password="a;b'c""d"

引用ルールは間違えやすいものです。 SqlConnectionStringBuilder プロパティを通じて値を設定し、ビルダーにそれらを引用させます。 詳細については、「 安全に接続文字列を構築する」をご覧ください。

ブール値を指定してください

ブール値を取るキーワードは、いずれの場合でも true、false、yes、no を受け付けます。 Integrated Security は sspi も受け入れるため、これは true を意味します。 ビルダーは True または False と書きます。

他のドライバーのキーワードを使う

Microsoft.Data.SqlClient では、Driver や Provider などの ODBC や OLE DB のキーワードは使用できません。 他のドライバーから接続文字列を移動する際には、これらのキーワードを削除してください。 System.Data.SqlClient 接続文字列は Microsoft.Data.SqlClient でも使用できますが、以下の違いがあります:

  • Encrypt の既定値は Microsoft.Data.SqlClient では Mandatory です。 信頼できる証明書を持たないサーバーは証明書検証に失敗します。 サーバーに信頼できる証明書をインストールしてください。
  • .NETでは、Network Library、Connection Reset、Transparent Network IP Resolutionはサポートされていません。 削除します。
  • Context Connection=trueはサポートされていません。
  • Asynchronous Processing はサポートされていないキーワードであるため、ArgumentException が発生します。 削除します。 非同期メソッドはそれなしでも動作します。
  • Type System Version=SQL Server 2000はサポートされていません。 接続を作成すると ArgumentException がスローされます。 Latest、SQL Server 2012、SQL Server 2008、またはSQL Server 2005を使ってください。