Reputation: 525
I have a simple flask-admin app. And I impersonate the app with logged user. The flask app runs well. But after a while, it recreates database connection and hit NT AUTHORITY\ANONYMOUS LOGON error. I have tried to disable the pool policy but doesn't help. the sqlalchemy database connection doesn't take the client logged user. Please help thanks.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
@contextmanager
def log_user():
"""Context manager for impersonating a user and getting the username."""
try:
if "X-IIS-WindowsAuthToken" in request.headers:
handle_str = request.headers.get("X-IIS-WindowsAuthToken")
handle = int(handle_str, 16)
win32security.ImpersonateLoggedOnUser(handle)
username = win32api.GetUserName()
yield username
else:
raise Exception("Missing authentication token")
finally:
win32security.RevertToSelf()
def impersonate(app):
@app.before_request
def impersonate_user():
"""Impersonate the user before executing each route."""
try:
# Start impersonation context manually
request.impersonation_context = log_user()
request.impersonation_context.__enter__()
except Exception as e:
return Response(
f"Authorization failed: {e}", mimetype="text/plain", status=401
)
@app.after_request
def revert_impersonation(response):
"""Revert user impersonation after the request has been processed."""
impersonation_context = getattr(request, "impersonation_context", None)
if impersonation_context:
# Revert impersonation after the request is completed
impersonation_context.__exit__(None, None, None)
return response
return app
app = Flask(__name__)
app = impersonate(app)
app.config["SQLALCHEMY_DATABASE_URI"] = "...."
...
# Initialize SQLAlchemy
db = SQLAlchemy(app)
# some table and some views
admin = Admin(
app,...)
File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in init self._dbapi_connection = engine.raw_connection() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3302, in raw_connection return self.pool.connect() ^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 449, in connect return _ConnectionFairy._checkout(self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1263, in _checkout fairy = _ConnectionRecord.checkout(pool) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout rec = pool._do_get() ^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 179, in _do_get with util.safe_reraise(): File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 146, in exit raise exc_value.with_traceback(exc_tb) File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 177, in _do_get return self._create_connection() ^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 390, in _create_connection return _ConnectionRecord(self) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in init self.__connect() File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect with util.safe_reraise(): File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 146, in exit raise exc_value.with_traceback(exc_tb) File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect self.dbapi_connection = connection = pool._invoke_creator(self) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 643, in connect return dialect.connect(*cargs, **cparams) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\inetpub\wwwroot\DreamLab.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 621, in connect return self.loaded_dbapi.connect(*cargs, **cparams) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pyodbc.InterfaceError: ('28000', "[28000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. (18456) (SQLDriverConnect); [28000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. (18456)")
Upvotes: 0
Views: 31