使用 Active Directory 连接到 Azure DB - 通用,并在 C# 中使用 MFA 支持身份验证

Pra*_*shi 8 c# azure azure-active-directory azure-sql-database multi-factor-authentication

我需要从 C# 控制台应用程序访问 SQL 表数据的某些部分。我需要帮助从 C# 建立服务器连接。

数据库详细信息:

 Server type : Database Engine
 Authentication : Active Directory-Universal with MFA support.
Run Code Online (Sandbox Code Playgroud)

另请让我知道我应该如何提供我的连接属性?

Dan*_*Dan 6

如果您不想摆弄令牌或将 C# 应用程序注册为 Azure 应用程序,则可以将 ODBC 或 OLE DB 与MSOLEDBSQL 驱动程序结合使用,该驱动程序能够开箱即用地使用 MFA / ActiveDirectoryInteractive 身份验证:

ODBC:

using System.Data.Odbc;
...
OdbcConnection con = new OdbcConnection("Driver={ODBC Driver 17 for SQL Server};SERVER=sqlserver.database.windows.net;DATABASE=database;Authentication=ActiveDirectoryInteractive;UID=user@domain.com");
Run Code Online (Sandbox Code Playgroud)

数据库:

using System.Data.OleDb;
...
OleDbConnection con = new OleDbConnection("Provider=MSOLEDBSQL;Data Source=sqlserver.database.windows.net;User ID=user@domain.com;Initial Catalog=database;Authentication=ActiveDirectoryInteractive");
Run Code Online (Sandbox Code Playgroud)


Sam*_*ucy 3

登录数据库有两种不同的场景。

1) 用户使用其帐户登录,您使用该令牌对 SQL 数据库进行身份验证。在这种情况下,您可以使用标准登录弹出窗口,它将为您处理 MFA 部分。

2) 用户没有数据库的权限(大多数标准 Web 应用程序都是这样的例子),或者您正在创建需要登录数据库的自动化服务。由于 MFA 的目的是让用户完成一些机器无法完成的操作,例如通过手机输入代码,因此无人值守登录不适用于 MFA。

如果您处于第二种情况,则需要创建一个不受 MFA 保护的服务主体帐户,以便应用程序登录。应用程序获取唯一的 appId 和 appSecret,而不是用户名和密码,用于访问数据库。您可以通过将机密放入 Key Vault 并将该应用程序的访问限制为仅其运行所需的特定资源来添加额外的保护。

请注意,在本例中,我们没有通过连接字符串传递用户名和密码。相反,我们在将令牌添加到连接之前单独获取令牌。

string serverName = "myserver.database.windows.net"; 
string databaseName = "test";
string clientId = "xxxxxx-xxxxx-xxxxx-xxxx-xxxx"; 
string aadTenantId = "xxxxxx-xxxxxx-xxxxxx-xxxxxx-xxxxxxxx";
string clientSecretKey = "xxxxx/xxxxxx/xxxxx";

string sqlConnectionString = String.Format("Data Source=tcp:{0},1433;Initial Catalog={1};Persist Security Info=False;Connect Timeout=30;Encrypt=True;TrustServerCertificate=False", serverName, databaseName);

string AadInstance = "https://login.windows.net/{0}";
string ResourceId = "https://database.windows.net/";


AuthenticationContext authenticationContext = new AuthenticationContext(string.Format(AadInstance, aadTenantId));
ClientCredential clientCredential = new ClientCredential(clientId, clientSecretKey);

DateTime startTime = DateTime.Now;
Console.WriteLine("Time " + String.Format("{0:mm:ss.fff}", startTime));

AuthenticationResult authenticationResult = authenticationContext.AcquireTokenAsync(ResourceId, clientCredential).Result;

DateTime endTime = DateTime.Now;
Console.WriteLine("Got token at " + String.Format("{0:mm:ss.fff}", endTime));

Console.WriteLine("Total time to get token in milliseconds " + (endTime - startTime).TotalMilliseconds);

using (var conn = new SqlConnection(sqlConnectionString))
{
     conn.AccessToken = authenticationResult.AccessToken;
     //DO STUFF
}
Run Code Online (Sandbox Code Playgroud)