连接到MSSQL Server使用{ODBC驱动程序 17 for SQL Server}和AD系统用户失败。

huangapple go评论140阅读模式
英文:

Connection to MSSQL Server with {ODBC Driver 17 for SQL Server} with AD system user fails

问题

I'm trying to connect a windows system user in my SQLAlchemy framework with an MSSQL Server.
I'm developing on an Max M1 with FreeTDS Driver with the same user. To connect, I set the authentification to "authentication" = "ActiveDirectoryPassword" and everthing works like a charm. When I try to run the same code on a windows machine with ODBC Driver insead of FreeTDS (with a different user than the user with the database access, so I can't simply use the trusted_connection="yes" argument) the connection is refused because the username is deleted in the connection string.

InterfaceError('(pyodbc.InterfaceError) (\'28000\', "[28000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user \'\' (18456) (SQLDriverConnect); [28000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user \'\' (18456)")')

I create my collection string like this:

  1. from sqlalchemy import create_engine
  2. if "MacBook" in socket.gethostname():
  3. driver = "FreeTDS"
  4. else:
  5. driver = "ODBC Driver 17 for SQL Server"
  6. self.db_api = "pyodbc"
  7. query_dict = {
  8. "driver": driver,
  9. "TrustServerCertificate": "yes",
  10. "authentication": "ActiveDirectoryPassword"
  11. }
  12. connection_url = URL.create(
  13. f"mssql+{self.db_api}",
  14. username=self.user,
  15. password=self.password,
  16. host=self.server,
  17. port=self.port,
  18. database=self.database,
  19. query=query_dict,
  20. )
  21. self.engine = create_engine(connection_url)
  22. con=Connection(self.engine)```
  23. On the mac I use Python 3.9.12 and SQLAlchemy==1.4.42.
  24. On the windows machine is a
  25. Edition Windows Server 2022 Datacenter
  26. Version 21H2
  27. Installed on ‎12/‎20/‎2022
  28. OS build 20348.1487
  29. with Python 3.9.2 and SQLAlchemy==1.4.42.
  30. I tried changing the driver to "ODBC Driver 18 for SQL Server" with the same outcome.
  31. When setting the "TrustServerCertificate" to "no " I get another error:
  32. ```OperationalError("(pyodbc.OperationalError) ('08001', '[08001] [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: The certificate chain was issued by an authority that is not trusted.\\r\\n (-2146893019) (SQLDriverConnect); [08001] [Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection")```
  33. I also tried disabling the Encryption and all the other authentifications provided [here](https://learn.microsoft.com/en-us/sql/connect/odbc/using-azure-active-directory?view=sql-server-ver16) without any effect.
  34. Leaving authentification method blank:
  35. '28000', "[28000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Login failed for user 'xxx\xxxx'
  36. Setting authentification method to "ActiveDirectoryIntegrated":
  37. ('FA002', "[FA002] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot use Authentication option 'ActiveDirectoryIntegrated' with User or Password options.
  38. <details>
  39. <summary>英文:</summary>
  40. I&#39;m trying to connect a windows system user in my SQLAlchemy framework with an MSSQL Server.
  41. I&#39;m developing on an Max M1 with FreeTDS Driver with the same user. To connect, I set the authentification to [&quot;authentication&quot;] = &quot;ActiveDirectoryPassword&quot; and everthing works like a charm. When I try to run the same code on a windows machine with ODBC Driver insead of FreeTDS (with a different user than the user with the database access, so I can&#39;t simply use the trusted_connection=&quot;yes&quot; argument) the connection is refused because the username is deleted in the connection string.

InterfaceError('(pyodbc.InterfaceError) (&#39;28000&#39;, "[28000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user &#39;&#39;. (18456) (SQLDriverConnect); [28000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user &#39;&#39;. (18456)")')

  1. I create my collection string like this:

from sqlalchemy.engine import URL
from sqlalchemy import create_engine

if "MacBook" in socket.gethostname():
driver = "FreeTDS"
else:
driver = "ODBC Driver 17 for SQL Server"
self.db_api = "pyodbc"

query_dict = {
"driver": driver,
"TrustServerCertificate": "yes",
"authentication": "ActiveDirectoryPassword"
}

connection_url = URL.create(
f"mssql+{self.db_api}",
username=self.user,
password=self.password,
host=self.server,
port=self.port,
database=self.database,
query=query_dict,
)
self.engine = create_engine(connection_url)
con=Connection(self.engine)

  1. On the mac I use Python 3.9.12 and SQLAlchemy==1.4.42.
  2. On the windows machine is a
  3. Edition Windows Server 2022 Datacenter
  4. Version 21H2
  5. Installed on 12/‎20/‎2022
  6. OS build 20348.1487
  7. with Python 3.9.2 and SQLAlchemy==1.4.42.
  8. I tried changing the driver to &quot;ODBC Driver 18 for SQL Server&quot; with the same outcome.
  9. When setting the &quot;TrustServerCertificate&quot; to &quot;no &quot; I get another error:

OperationalError("(pyodbc.OperationalError) ('08001', '[08001] [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: The certificate chain was issued by an authority that is not trusted.\r\n (-2146893019) (SQLDriverConnect); [08001] [Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection

  1. I also tried disabling the Encryption and all the other authentifications provided [here](https://learn.microsoft.com/en-us/sql/connect/odbc/using-azure-active-directory?view=sql-server-ver16) without any effect.
  2. Leaving authentification method blank:
  3. &#39;28000&#39;, &quot;[28000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Login failed for user &#39;xxx\\xxxx&#39;
  4. Setting authentification method to &quot;ActiveDirectoryIntegrated&quot;:
  5. (&#39;FA002&#39;, &quot;[FA002] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Cannot use Authentication option &#39;ActiveDirectoryIntegrated&#39; with User or Password options.
  6. </details>
  7. # 答案1
  8. **得分**: 0
  9. 在[这个][1]答案中找到了解决我的问题的方法!
  10. 不确定是否遇到了pyodbc包中的错误或其他问题,但将db_api更改为pymssql就解决了问题!
  11. 我的连接字符串现在如下:
  12. ```python
  13. if "MacBook" in socket.gethostname():
  14. driver = "FreeTDS"
  15. self.db_api = "pyodbc"
  16. query_dict = {
  17. "driver": driver,
  18. "TrustServerCertificate": "yes",
  19. "authentication": "ActiveDirectoryPassword"
  20. }
  21. else:
  22. driver = "ODBC Driver 17 for SQL Server"
  23. self.db_api = "pymssql"
  24. query_dict = {
  25. }
  26. connection_url = URL.create(
  27. f"mssql+{self.db_api}",
  28. username=self.user,
  29. password=self.password,
  30. host=self.server,
  31. port=self.port,
  32. database=self.database,
  33. query=query_dict,
  34. )
英文:

Found a solution for my problem in this answer!
Not sure if I stumbled upon a bug in the pyodbc package or what but changing the db_api to pymssql did the trick!
My connection string now is as follows:

  1. if &quot;MacBook&quot; in socket.gethostname():
  2. driver = &quot;FreeTDS&quot;
  3. self.db_api = &quot;pyodbc&quot;
  4. query_dict = {
  5. &quot;driver&quot;: driver,
  6. &quot;TrustServerCertificate&quot;: &quot;yes&quot;,
  7. &quot;authentication&quot;: &quot;ActiveDirectoryPassword&quot;
  8. }
  9. else:
  10. driver = &quot;ODBC Driver 17 for SQL Server&quot;
  11. self.db_api = &quot;pymssql&quot;
  12. query_dict = {
  13. }
  14. connection_url = URL.create(
  15. f&quot;mssql+{self.db_api}&quot;,
  16. username=self.user,
  17. password=self.password,
  18. host=self.server,
  19. port=self.port,
  20. database=self.database,
  21. query=query_dict,
  22. )

huangapple
  • 本文由 发表于 2023年2月24日 01:56:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75548576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定