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

时间:2019-05-20 06:57:21

标签: c# azure azure-active-directory azure-sql-database mfa

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

数据库详细信息:

 Server type : Database Engine
 Authentication : Active Directory-Universal with MFA support.

也请让我知道如何给我连接属性?

2 个答案:

答案 0 :(得分:1)

如果您不想摆弄令牌或将C#应用程序注册为Azure应用程序,则可以将ODBC或OLE DB与MSOLEDBSQL driver一起使用,它可以使用MFA / ActiveDirectoryInteractive身份验证来代替框:

ODBC:

version: '3'
services:

  webserver:
    image: nginx:alpine
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./apps/curator/:/var/www/curator
      - ./apps/dispenser/:/var/www/dispenser
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./docker/nginx/sites/:/etc/nginx/conf.d/
      - ./docker/nginx/ssl/:/etc/ssl/
    networks:
      - app-network

  curator:
    build:
      context: apps/curator
      dockerfile: Dockerfile
    image: digitalocean.com/php
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: curator
      SERVICE_TAGS: dev
    working_dir: /var/www/curator
    volumes:
      - ./apps/curator/:/var/www/curator
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

  dispenser:
    build:
      context: apps/dispenser
      dockerfile: Dockerfile
    image: digitalocean.com/php
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: dispenser
      SERVICE_TAGS: dev
    working_dir: /var/www/dispenser
    volumes:
      - ./apps/dispenser/:/var/www/dispenser
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  dbdata:
    driver: local

OLE DB:

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");

答案 1 :(得分:0)

登录数据库有两种不同的方案。

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
}