J'essaie de me connecter d'une machine Linux à un serveur Windows SQL avec pyodbc.
J'ai quelques contraintes:
J'ai installé l'environnement comme décrit par Microsoft et l'ai fait fonctionner (je peux importer pyodbc et utiliser le pilote de moule configuré).
Je ne suis pas familier avec l'authentification de domaine Windows et quoi d'autre, donc il y a où est mon problème.
Ma chaîne de connexion:
DRIVER={ODBC Driver 17 for SQL Server};SERVER=myserver.mydomain.com;PORT=1433;DATABASE=MyDatabase;Domain=MyCompanyDomain;Instance=MyInstance;UID=myDomainUser;PWD=XXXXXXXX;Trusted_Connection=yes;Integrated_Security=SSPI
Soi-disant, on devrait utiliser "Trusted_Connection" pour utiliser l'authentification de domaine Windows au lieu de s'authentifier directement avec le serveur SQL.
L'erreur que j'obtiens lors de l'exécution pyodbc.connect (connString) :
pyodbc.Error: ('HY000', '[HY000] [unixODBC][Microsoft][ODBC Driver 17 for SQL Server]SSPI Provider: No Kerberos credentials available (851968) (SQLDriverConnect)')
À partir d'autres sources, j'ai lu que cela devrait fonctionner sur Windows car ce code utiliserait les informations d'identification de l'utilisateur actuellement connecté.
Ma question est de savoir comment puis-je me connecter à une instance Windows SQL Server à partir de Linux à l'aide des informations d'identification de domaine Windows.
J'ai fini par utiliser la bibliothèque pymssql qui est fondamentalement pyodbc en plus du pilote FreeTDS. Cela a fonctionné hors de la boîte.
Bizarre comment j'ai eu du mal à découvrir cette bibliothèque ..
Vous devez obtenir un ticket Kerberos pour que cela fonctionne. Votre exemple ne spécifie pas si votre système Linux est configuré pour s'authentifier via Kerberos ou si vous avez précédemment obtenu un ticket Kerberos avant que votre code ne frappe votre chaîne de connexion.
Si votre système Linux est configuré pour s'authentifier via Kerberos, comme preuve de concept, vous pouvez obtenir un ticket Kerberos en utilisant kinit à partir de la ligne de commande. Voici ce qui fonctionne pour moi en python3 fonctionnant sous Ubuntu sur Windows via le WSL. Le code python:
#!/usr/bin/env python
# minimal example using Kerberos auth
import sys
import re
import pyodbc
driver='{ODBC Driver 17 for SQL Server}'
server = sys.argv[1]
database = sys.argv[2]
# trusted_connection uses kerberos ticket and ignores UID and PASSWORD in connection string
# https://docs.Microsoft.com/en-us/sql/connect/odbc/linux-mac/using-integrated-authentication?view=sql-server-ver15
try:
cnxn = pyodbc.connect(driver=driver, server=server, database=database, trusted_connection='yes')
cursor = cnxn.cursor()
except pyodbc.Error as ex:
msg = ex.args[1]
if re.search('No Kerberos', msg):
print('You must login using kinit before using this script.')
exit(1)
else:
raise
# Sample select query
cursor.execute("SELECT @@version;")
row = cursor.fetchone()
while row:
print(row[0])
row = cursor.fetchone()
print('success')
Cela vous indique si vous n'avez pas de ticket. Puisqu'il utilise un ticket, vous n'avez pas besoin de spécifier un utilisateur ou un mot de passe dans le script. Il ignorera les deux.
Maintenant, nous l'exécutons:
user@localhost:~# kdestroy # make sure there are no active tickets
kdestroy: No credentials cache found while destroying cache
user@localhost:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
You must login using kinit before using this script.
user@localhost:~# kinit
Password for [email protected]:
user@localhost:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
Microsoft SQL Server 2016 (SP2-GDR) (KB4505220) - 13.0.5101.9 (X64)
Jun 15 2019 23:15:58
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: )
success
user@localhost:~#
Vous pouvez également réussir à obtenir un ticket Kerberos à partir de python qui s'exécute avant d'établir cette connexion mais qui dépasse le cadre de cette réponse. Une recherche de python = Les modules Kerberos peuvent vous orienter vers une solution.
Il semble également possible de configurer le système Linux de sorte que dès qu'un utilisateur se connecte, il obtienne automatiquement un ticket Kerberos qui peut être transmis à d'autres processus. Cela est également en dehors de la portée de cette réponse, mais une recherche de ticket Kerberos automatique lors de la connexion Linux peut donner des indices.
J'essayais de faire la même chose et après avoir lu la réponse OP, j'ai testé pymssql et j'ai remarqué que cela fonctionnait avec juste ce qui suit:
pymssql.connect(server='myserver', user='domain\username', password='password', database='mydb')
Après avoir réalisé que c'était tout ce dont pymssql avait besoin, je suis retourné à pyodbc et j'ai pu le faire fonctionner avec:
pyodbc.connect("DRIVER={FreeTDS};SERVER=myserver;PORT=1433;DATABASE=mydb;UID=domain\username;PWD=password;TDS_Version=8.0")
La génération de l'authentification Windows via Linux est complexe. EasySoftDB (commercial) était capable de gérer cela, et FreeTDS a un support compliqué.
https://docs.Microsoft.com/en-us/sql/connect/odbc/linux-mac/using-integrated-authentication
Ma suggestion est de s'éloigner de l'authentification Windows et d'utiliser l'authentification SQL. Il n'y a vraiment aucune différence de sécurité, sauf que vous fournissez un nom d'utilisateur et un mot de passe dans la chaîne de connexion. Mais cela vous rendrait la vie beaucoup plus facile.