使用MFA Active Directory交互式身份验证以Python连接到Azure SQL,而无需使用Microsoft.IdentityModel.Clients.ActiveDirectory dll

时间:2019-10-17 20:43:44

标签: azure odbc azure-sql-database pyodbc mfa

要使用MFA(在SSMS中为“ Active Directory-通用”,在MMS中连接)连接到Azure SQL数据库,Microsoft建议并且当前仅提供有关使用Microsoft.IdentityModel.Clients.ActiveDirectory与C#连接的教程。

在Python或Powershell的常规ODBC连接字符串中设置Authentication='Active Directory Interactive';会导致错误

Cannot find an authentication provider for 'ActiveDirectoryInteractive'

这似乎是因为根据https://docs.microsoft.com/en-us/azure/sql-database/active-directory-interactive-connect-azure-sql-db上Microsoft的示例代码,您需要在创建连接时显式创建自己的身份验证提供程序类:


        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();
        }

我想与pyodbc连接,所以我不能实现ActiveDirectoryInteractive提供程序。

是否可以使用OAuth以常规方式获取令牌并在连接字符串中使用令牌,或者以其他方式实现ActiveDirectoryInteractive提供程序而不使用.NET?

2 个答案:

答案 0 :(得分:2)

从 MacOS/Linux 使用 AAD MFA 进行身份验证

我在 MacO 上遇到了同样的问题。如上所述,使用“ActiveDirectoryInteractive”的 ODBC 选项仅适用于 Windows。

为了使用 AAD MFA 连接到数据库,我还使用了 pyodbc,但使用了访问令牌。要获得令牌,您需要做一些事情:

要求

  1. Azure CLI

  2. Microsoft ODBC Driver for SQL Server (Linux-MAC)

说明

在运行下面的代码之前,您必须使用 azure cli 进行身份验证,从 cmd 运行:az login

   func getUserTransition(){
        // process
        /*
         1.get all transition from tm_members sender and receiver by current user login 
         2.
         */
        guard let username = self.userSession?.username else {
            return
        }
        print("username in user session : \(username)")
        COLLECTION_TM_TRANSITIONS_UAT
            .whereField("sender_name", isEqualTo: username)
            .whereField("receiver_name", isEqualTo: username)
            .getDocuments { documentSnapshot, error in
            if error == nil {
                guard let value = documentSnapshot?.documents else { return }
           
                self.tmTransitions = value.map { (queryDocumentSnapshot) -> TmTransition in
                    let data = queryDocumentSnapshot.data()
                    let email = data["email"] as? String ?? ""
                    let is_sender = data["is_sender"] as? Bool ?? false
                    let point = data["point"] as? Int ?? 0
                    let username = data["username"] as? String ?? ""
                    let sender_id = data["sender_id"] as? String ?? ""
                    let receiver_id = data["receiver_id"] as? String ?? ""
                    let created_at = data["created_at"] as? Timestamp
                    let sender_name = data["sender_name"] as? String ?? ""
                    let receiver_name = data["receiver_name"] as? String ?? ""
                    print("username : \(email)")
                    return TmTransition(id: queryDocumentSnapshot.documentID, sender_id: sender_id, receiver_id: receiver_id, username: username, is_sender: is_sender, point: point, email: email,created_at: created_at,sender_name: sender_name,receiver_name: receiver_name)
              
                }
              
            }
            else{
                print("error during fetch data ")
            }
        }
    }

参考资料

https://pypi.org/project/azure-identity/

https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki/Connect-to-Azure-SQL-Database

答案 1 :(得分:1)

enter image description here支持MFA身份验证,但仅Windows: enter image description here

我在Python pyodbc中测试过,它也可以工作。

这是我的pyodbc代码,它们通过AAD MFA身份验证连接到我的Azure SQL数据库:

import pyodbc
server = '***.database.windows.net'
database = 'Mydatabase'
username ='****@****.com'
Authentication='ActiveDirectoryInteractive'
driver= '{ODBC Driver 17 for SQL Server}'
conn = pyodbc.connect('DRIVER='+driver+
                      ';SERVER='+server+
                      ';PORT=1433;DATABASE='+database+
                      ';UID='+username+
                      ';AUTHENTICATION='+Authentication
                      )

print(conn)

它在我的Windows环境中运作良好。 {{3}}

希望这会有所帮助。