Microsoft.Data.SqlClient の接続文字列は、セミコロンで区切られた keyword=value のペアのリストです。
SqlConnectionかSqlConnectionStringBuilderにパスしてください:
Server=tcp:sql.example.com,1433;Database=Orders;Integrated Security=true;Encrypt=Strict
接続文字列は、次の 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を使ってください。