我已经配置了我的 Azure SQL Server,以便我成为服务器管理员,我的帐户也启用了 MFA。我试图关注this documentation但它没有提及任何有关使用 MFA 的 Active Directory。
我可以使用我的帐户和 MFA 通过 SQL Management studio 正常登录服务器
最初我尝试过(基于新的 SqlAuthenticationMethod Enum ):
SqlConnection con = new SqlConnection("Server=tcp:myapp.database.windows.net;Database=CustomerDB;Authentication=Active Directory Interactive;Encrypt=True;<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a2f7ebe69ff7d1c7d0e2f7d1c7d08cc1cd8cd7c9" rel="noreferrer noopener nofollow">[email protected]</a>"))
错误:
'Cannot find an authentication provider for 'ActiveDirectoryInteractive'.'
然后我看到了this about accessing SQL via an Azure application但这不是我想做的。
这个SO question讨论在没有提供程序的情况下进行连接以及在连接字符串中设置 Driver
SqlConnection con = new SqlConnection("DRIVER={ODBC Driver 17 for SQL Server};Server=tcp:myapp.database.windows.net;Database=CustomerDB;Authentication=Active Directory Interactive;Encrypt=True;<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1a4f535e274f697f685a4f697f68347975346f71" rel="noreferrer noopener nofollow">[email protected]</a>"))
但我收到错误:
'Keyword not supported: 'driver'.'
是否可以编写一个连接字符串,以便在尝试连接时弹出 Microsoft 身份验证框以引导用户完成多重身份验证?
最佳答案
要使用 Azure AD 身份验证,您的 C# 程序必须注册为 Azure AD 应用程序。完成应用程序注册会生成并显示应用程序 ID。您的程序必须包含此 ID 才能连接。要注册应用程序并设置必要的权限,请转到 Azure 门户,选择 Azure Active Directory > 应用程序注册 > 新注册。
应用注册创建后,会生成并显示应用ID值。
选择 API 权限 > 添加权限。
选择我的组织使用的 API > 在搜索中输入 Azure SQL 数据库 > 然后选择 Azure SQL 数据库。
选择委派权限 > user_impersonation > 添加权限。
您似乎已经为 Azure SQL 数据库设置了 Azure AD 管理员。
您还可以使用 SQL 创建用户命令将用户添加到数据库。一个例子是 CREATE USER [] FROM EXTERNAL PROVIDER。欲了解更多信息,请参阅here .
下面是 C# 的示例。
using System;
// Reference to Azure AD authentication assembly
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using DA = System.Data;
using SC = System.Data.SqlClient;
using AD = Microsoft.IdentityModel.Clients.ActiveDirectory;
using TX = System.Text;
using TT = System.Threading.Tasks;
namespace ADInteractive5
{
class Program
{
// ASSIGN YOUR VALUES TO THESE STATIC FIELDS !!
static public string Az_SQLDB_svrName = "<Your SQL DB server>";
static public string AzureAD_UserID = "<Your User ID>";
static public string Initial_DatabaseName = "<Your Database>";
// Some scenarios do not need values for the following two fields:
static public readonly string ClientApplicationID = "<Your App ID>";
static public readonly Uri RedirectUri = new Uri("<Your URI>");
public static void Main(string[] args)
{
var provider = new ActiveDirectoryAuthProvider();
SC.SqlAuthenticationProvider.SetProvider(
SC.SqlAuthenticationMethod.ActiveDirectoryInteractive,
//SC.SqlAuthenticationMethod.ActiveDirectoryIntegrated, // Alternatives.
//SC.SqlAuthenticationMethod.ActiveDirectoryPassword,
provider);
Program.Connection();
}
public static void Connection()
{
SC.SqlConnectionStringBuilder builder = new SC.SqlConnectionStringBuilder();
// Program._ static values that you set earlier.
builder["Data Source"] = Program.Az_SQLDB_svrName;
builder.UserID = Program.AzureAD_UserID;
builder["Initial Catalog"] = Program.Initial_DatabaseName;
// This "Password" is not used with .ActiveDirectoryInteractive.
//builder["Password"] = "<YOUR PASSWORD HERE>";
builder["Connect Timeout"] = 15;
builder["TrustServerCertificate"] = true;
builder.Pooling = false;
// Assigned enum value must match the enum given to .SetProvider().
builder.Authentication = SC.SqlAuthenticationMethod.ActiveDirectoryInteractive;
SC.SqlConnection sqlConnection = new SC.SqlConnection(builder.ConnectionString);
SC.SqlCommand cmd = new SC.SqlCommand(
"SELECT '******** MY QUERY RAN SUCCESSFULLY!! ********';",
sqlConnection);
try
{
sqlConnection.Open();
if (sqlConnection.State == DA.ConnectionState.Open)
{
var rdr = cmd.ExecuteReader();
var msg = new TX.StringBuilder();
while (rdr.Read())
{
msg.AppendLine(rdr.GetString(0));
}
Console.WriteLine(msg.ToString());
Console.WriteLine(":Success");
}
else
{
Console.WriteLine(":Failed");
}
sqlConnection.Close();
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Connection failed with the following exception...");
Console.WriteLine(ex.ToString());
Console.ResetColor();
}
}
} // EOClass Program.
/// <summary>
/// SqlAuthenticationProvider - Is a public class that defines 3 different Azure AD
/// authentication methods. The methods are supported in the new .NET 4.7.2.
/// .
/// 1. Interactive, 2. Integrated, 3. Password
/// .
/// All 3 authentication methods are based on the Azure
/// Active Directory Authentication Library (ADAL) managed library.
/// </summary>
public class ActiveDirectoryAuthProvider : SC.SqlAuthenticationProvider
{
// Program._ more static values that you set!
private readonly string _clientId = Program.ClientApplicationID;
private readonly Uri _redirectUri = Program.RedirectUri;
public override async TT.Task<SC.SqlAuthenticationToken>
AcquireTokenAsync(SC.SqlAuthenticationParameters parameters)
{
AD.AuthenticationContext authContext =
new AD.AuthenticationContext(parameters.Authority);
authContext.CorrelationId = parameters.ConnectionId;
AD.AuthenticationResult result;
switch (parameters.AuthenticationMethod)
{
case SC.SqlAuthenticationMethod.ActiveDirectoryInteractive:
Console.WriteLine("In method 'AcquireTokenAsync', case_0 == '.ActiveDirectoryInteractive'.");
result = await authContext.AcquireTokenAsync(
parameters.Resource, // "https://database.windows.net/"
_clientId,
_redirectUri,
new AD.PlatformParameters(AD.PromptBehavior.Auto),
new AD.UserIdentifier(
parameters.UserId,
AD.UserIdentifierType.RequiredDisplayableId));
break;
case SC.SqlAuthenticationMethod.ActiveDirectoryIntegrated:
Console.WriteLine("In method 'AcquireTokenAsync', case_1 == '.ActiveDirectoryIntegrated'.");
result = await authContext.AcquireTokenAsync(
parameters.Resource,
_clientId,
new AD.UserCredential());
break;
case SC.SqlAuthenticationMethod.ActiveDirectoryPassword:
Console.WriteLine("In method 'AcquireTokenAsync', case_2 == '.ActiveDirectoryPassword'.");
result = await authContext.AcquireTokenAsync(
parameters.Resource,
_clientId,
new AD.UserPasswordCredential(
parameters.UserId,
parameters.Password));
break;
default: throw new InvalidOperationException();
}
return new SC.SqlAuthenticationToken(result.AccessToken, result.ExpiresOn);
}
public override bool IsSupported(SC.SqlAuthenticationMethod authenticationMethod)
{
return authenticationMethod == SC.SqlAuthenticationMethod.ActiveDirectoryIntegrated
|| authenticationMethod == SC.SqlAuthenticationMethod.ActiveDirectoryInteractive
|| authenticationMethod == SC.SqlAuthenticationMethod.ActiveDirectoryPassword;
}
} // EOClass ActiveDirectoryAuthProvider.
} // EONamespace. End of entire program source code.
The example above relies on the Microsoft.IdentityModel.Clients.ActiveDirectory DLL 汇编。
要安装此包,请在 Visual Studio 中选择“项目”>“管理 NuGet 包”。搜索并安装 Microsoft.IdentityModel.Clients.ActiveDirectory。
从 .NET Framework 版本 4.7.2 开始,枚举 SqlAuthenticationMethod 具有新值:ActiveDirectoryInteractive。
关于c# - 如何使用 Active Directory 登录和多重身份验证 (MFA) 连接到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60564462/