Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Utilisez SqlConnectionStringBuilder pour créer et modifier des chaînes de connexion via des propriétés typées. Il hérite de DbConnectionStringBuilder. Utilisez-le chaque fois que votre code ajoute ou modifie une valeur, au lieu de concaténer des chaînes.
Le constructeur :
- Expose chaque mot-clé comme une propriété typée, comme
ConnectTimeoutcomme un int etEncryptcomme unSqlConnectionEncryptOption. - Rejette des mots-clés inconnus et de nombreuses valeurs hors plage avec ArgumentException lorsque vous les définissez.
- Associe des synonymes tels que
Serveretuidà des mots-clés canoniques tels queData SourceetUser ID. - Met entre guillemets les valeurs contenant des points-virgules, des guillemets ou des espaces au début ou à la fin.
Pour la liste des mots-clés, voir Options de connexion. Pour le format textuel, voir règles d’analyse.
Chaque échantillon est un programme complet. Les onglets .NET Framework utilisent C# 7.3. Pour créer un projet qui exécute les exemples, voir Créer le projet.
Empêcher l’injection de chaîne de connexion
Lorsque votre code insère un texte non fiable dans une chaîne de connexion, un point-virgule dans ce texte peut ajouter un mot-clé ou remplacer un précédent, car la dernière valeur l’emporte. Le builder stocke la totalité de la valeur dans une seule propriété et la met entre guillemets, donc le texte ne peut pas devenir un autre mot-clé.
Ce programme fixe InitialCatalog à une valeur qui tente de désactiver le pooling :
using Microsoft.Data.SqlClient;
// Simulates a value that came from a user or another untrusted source.
string databaseFromUser = "Orders;Pooling=false";
var builder = new SqlConnectionStringBuilder
{
DataSource = "tcp:sql.example.com,1433",
InitialCatalog = databaseFromUser,
IntegratedSecurity = true,
Encrypt = SqlConnectionEncryptOption.Strict,
};
Console.WriteLine(builder.ConnectionString);
Console.WriteLine($"Pooling: {builder.Pooling}");
La sortie est la suivante :
Data Source=tcp:sql.example.com,1433;Initial Catalog="Orders;Pooling=false";Integrated Security=True;Encrypt=Strict
Pooling: True
Le générateur met la valeur entre guillemets, et Pooling reste True. Le pilote envoie Orders;Pooling=false au serveur comme nom de la base de données.
Mettre entre guillemets empêche l’injection de mots-clés. Il ne décide pas si une valeur est autorisée. Vérifiez l’entrée non fiable par rapport à une liste de serveurs ou bases de données autorisées avant de l’utiliser.
Complétez une chaîne de connexion de base
Stockez les parties d'une chaîne de connexion qui ne changent pas, comme le serveur et la base de données, en configuration. Ajoutez les valeurs secrètes et spécifiques à la charge de travail à l’exécution. Passez la chaîne de base au constructeur du builder, puis définissez les propriétés.
Ce programme lit une chaîne de base et un mot de passe provenant de variables d’environnement distinctes, se connecte avec l’authentification SQL et confirme que le mot de passe n’est pas visible après l’ouverture de la connexion.
using Microsoft.Data.SqlClient;
// The base string holds no secret. The password comes from a separate secret source.
string baseConnectionString =
Environment.GetEnvironmentVariable("SQL_BASE_CONNECTION_STRING")
?? throw new InvalidOperationException(
"Set the SQL_BASE_CONNECTION_STRING environment variable.");
string password =
Environment.GetEnvironmentVariable("SQL_PASSWORD")
?? throw new InvalidOperationException(
"Set the SQL_PASSWORD environment variable.");
var builder = new SqlConnectionStringBuilder(baseConnectionString)
{
Password = password,
ApplicationName = "Orders.Worker",
};
await using var connection = new SqlConnection(builder.ConnectionString);
await connection.OpenAsync();
await using var command = new SqlCommand("SELECT APP_NAME();", connection);
Console.WriteLine($"APP_NAME(): {await command.ExecuteScalarAsync()}");
var opened = new SqlConnectionStringBuilder(connection.ConnectionString);
Console.WriteLine($"Password visible after open: {opened.ContainsKey("Password") && opened.Password.Length > 0}");
Définissez SQL_BASE_CONNECTION_STRING à une valeur telle que Server=tcp:<server>,1433;Database=<database>;User ID=<user>;Encrypt=true. La sortie est la suivante :
APP_NAME(): Orders.Worker
Password visible after open: False
Persist Security Info a pour valeur par défaut false, donc le pilote supprime le mot de passe de SqlConnection.ConnectionString après l’ouverture de la connexion. Gardez cette valeur par défaut.
Privilégiez une méthode d’authentification sans mot de passe, comme l’authentification intégrée Windows ou une identité gérée Microsoft Entra ID. Pour plus d’informations, voir l’authentification Microsoft Entra ID et Protéger les informations de connexion.
Lire et modifier des valeurs
Le constructeur fonctionne aussi comme un dictionnaire. L’indexeur, ContainsKey, Remove, et TryGetValue acceptent un mot-clé ou l’un de ses synonymes.
using Microsoft.Data.SqlClient;
var b = new SqlConnectionStringBuilder("Server=sql.example.com;Database=Orders;uid=app_user;pwd=x");
b["server"] = "tcp:sql2.example.com,1433";
Console.WriteLine($"DataSource: {b.DataSource}");
Console.WriteLine($"ContainsKey(\"uid\"): {b.ContainsKey("uid")}");
Console.WriteLine($"Remove(\"pwd\"): {b.Remove("pwd")}");
Console.WriteLine($"TryGetValue: {b.TryGetValue("Database", out object? db)} {db}");
Console.WriteLine($"ShouldSerialize(\"Pooling\"): {b.ShouldSerialize("Pooling")}");
Console.WriteLine(b.ConnectionString);
try { b["Bogus"] = 1; } catch (Exception e) { Console.WriteLine($"{e.GetType().Name}: {e.Message}"); }
try { b.ConnectTimeout = -1; } catch (Exception e) { Console.WriteLine($"{e.GetType().Name}: {e.Message}"); }
La sortie est la suivante :
DataSource: tcp:sql2.example.com,1433
ContainsKey("uid"): True
Remove("pwd"): True
TryGetValue: True Orders
ShouldSerialize("Pooling"): False
Data Source=tcp:sql2.example.com,1433;Initial Catalog=Orders;User ID=app_user
ArgumentException: Keyword not supported: 'Bogus'.
ArgumentException: Invalid value for key 'Connect Timeout'.
ShouldSerialize renvoie false pour un mot-clé qui n’est pas dans la chaîne.
ContainsKey retourne true pour chaque mot-clé pris en charge, que la chaîne le définisse ou non. La ConnectionString propriété ne contient que les mots-clés que vous avez définis.
Comprenez ce que le générateur ne vérifie pas
Le builder rejette des mots-clés inconnus et de nombreuses valeurs invalides, mais il ne vérifie pas toutes les valeurs. Par exemple, il accepte tout texte pour Type System Version et Transaction Binding, et ne vérifie pas la longueur des chaînes. Il ne vérifie pas non plus les combinaisons de mots-clés, donc il accepte Authentication=Active Directory Default avec Integrated Security=true.
SqlConnection Rejette cette combinaison avec ArgumentException quand tu passes la chaîne de caractères. Pour la liste complète des règles, voir Règles de validation.
Le constructeur écrit les valeurs Authentication sans espaces, telles que Authentication=ActiveDirectoryDefault. Le pilote accepte les deux formats.
Le générateur ne protège pas non plus un mot de passe après son entrée en mémoire de processus, et il ne décide pas si un réglage serveur, identité ou certificat est sûr.
Conservez une chaîne de connexion canonique
Chaque chaîne de connexion distincte possède son propre pool de connexions. Deux chaînes manuscrites qui ne diffèrent que par la séquence des mots-clés ou par les synonymes créent deux groupes. Le constructeur écrit les mots-clés canoniques dans un ordre cohérent, donc Server=a;Database=d et Database=d;Server=a deviennent tous deux Data Source=a;Initial Catalog=d. Construisez la chaîne de connexion une fois au démarrage et réutilisez-labuilder.ConnectionString. N’ajoutez pas de valeurs par requête, comme les noms d’utilisateur ou les identifiants de requête. Pour plus de conseils sur le pooling, voir Utiliser le pooling de connexions.