最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Passing Microsoft MFA Authentication from Databricks to SQL Server Managed Instance in a Databricks FastAPI App - Stack Overflow

programmeradmin2浏览0评论

I have a Databricks App built using FastAPI. Users access this App after authenticating with Microsoft MFA on Databricks Azure Cloud. The App connects to a SQL Server Managed Instance (MI) that also supports Microsoft MFA.

I want the authenticated user's credentials to be passed to the App and used for database connections. In the development environment, this works fine since I am logged in with my Microsoft MFA. Can this be achieved in a Databricks App?

Below is a snippet of the code I am using with SQLAlchemy and PyODBC

from sqlalchemy import create_engine, event, text
from azure.identity import DefaultAzureCredential
import struct
import pyodbc

try:
    azure_credentials = DefaultAzureCredential()
    
    TOKEN_URL = "/"
    SQL_COPT_SS_ACCESS_TOKEN = 1256  

    server = 'azsql-mi-xyz.database.windows'
    port = "1234"
    database = 'database'
    driver = "ODBC Driver 18 for SQL Server"

    conn_str = f"mssql+pyodbc://@{server}:{port}/{database}?driver={driver}"
    engine = create_engine(conn_str)

    @event.listens_for(engine, "do_connect")
    def provide_token(dialect, conn_rec, cargs, cparams):
        # Remove "Trusted_Connection" parameter added by SQLAlchemy
        cargs[0] = cargs[0].replace(";Trusted_Connection=Yes", "")

        # Generate token credential
        raw_token = azure_credentials.get_token(TOKEN_URL).token.encode("utf-16-le")
        token_struct = struct.pack(f"<I{len(raw_token)}s", len(raw_token), raw_token)

        # Apply it to connection parameters
        cparams["attrs_before"] = {SQL_COPT_SS_ACCESS_TOKEN: token_struct}

    # Test the connection
    with engine.connect() as connection:
        query = text("SELECT * FROM tablex")
        rows = connection.execute(query).fetchall()
    
    data = [dict(row._mapping) for row in rows]
    return {"data": data}

except Exception as e:
    raise HTTPException(status_code=500, detail=f"General Error: {str(e)}")

Below is the error message from the application

General Error: DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
EnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
Visit to troubleshoot this issue.\n\tManagedIdentityCredential: ManagedIdentityCredential authentication unavailable, no response from the IMDS endpoint.
SharedTokenCacheCredential: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
AzureCliCredential: Azure CLI not found on path
AzurePowerShellCredential: PowerShell is not installed
AzureDeveloperCliCredential: Azure Developer CLI could not be found. Please visit for installation instructions and then,once installed, authenticate to your Azure account using 'azd auth login'.
To mitigate this issue, please refer to the troubleshooting guidelines here at
.

I have a Databricks App built using FastAPI. Users access this App after authenticating with Microsoft MFA on Databricks Azure Cloud. The App connects to a SQL Server Managed Instance (MI) that also supports Microsoft MFA.

I want the authenticated user's credentials to be passed to the App and used for database connections. In the development environment, this works fine since I am logged in with my Microsoft MFA. Can this be achieved in a Databricks App?

Below is a snippet of the code I am using with SQLAlchemy and PyODBC

from sqlalchemy import create_engine, event, text
from azure.identity import DefaultAzureCredential
import struct
import pyodbc

try:
    azure_credentials = DefaultAzureCredential()
    
    TOKEN_URL = "https://database.windows/"
    SQL_COPT_SS_ACCESS_TOKEN = 1256  

    server = 'azsql-mi-xyz.database.windows'
    port = "1234"
    database = 'database'
    driver = "ODBC Driver 18 for SQL Server"

    conn_str = f"mssql+pyodbc://@{server}:{port}/{database}?driver={driver}"
    engine = create_engine(conn_str)

    @event.listens_for(engine, "do_connect")
    def provide_token(dialect, conn_rec, cargs, cparams):
        # Remove "Trusted_Connection" parameter added by SQLAlchemy
        cargs[0] = cargs[0].replace(";Trusted_Connection=Yes", "")

        # Generate token credential
        raw_token = azure_credentials.get_token(TOKEN_URL).token.encode("utf-16-le")
        token_struct = struct.pack(f"<I{len(raw_token)}s", len(raw_token), raw_token)

        # Apply it to connection parameters
        cparams["attrs_before"] = {SQL_COPT_SS_ACCESS_TOKEN: token_struct}

    # Test the connection
    with engine.connect() as connection:
        query = text("SELECT * FROM tablex")
        rows = connection.execute(query).fetchall()
    
    data = [dict(row._mapping) for row in rows]
    return {"data": data}

except Exception as e:
    raise HTTPException(status_code=500, detail=f"General Error: {str(e)}")

Below is the error message from the application

General Error: DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
EnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
Visit https://aka.ms/azsdk/python/identity/environmentcredential/troubleshoot to troubleshoot this issue.\n\tManagedIdentityCredential: ManagedIdentityCredential authentication unavailable, no response from the IMDS endpoint.
SharedTokenCacheCredential: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
AzureCliCredential: Azure CLI not found on path
AzurePowerShellCredential: PowerShell is not installed
AzureDeveloperCliCredential: Azure Developer CLI could not be found. Please visit https://aka.ms/azure-dev for installation instructions and then,once installed, authenticate to your Azure account using 'azd auth login'.
To mitigate this issue, please refer to the troubleshooting guidelines here at
https://aka.ms/azsdk/python/identity/defaultazurecredential/troubleshoot.

Share Improve this question edited Mar 14 at 21:43 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 14 at 16:15 Obirieni SimeoObirieni Simeo 998 bronze badges 2
  • Exactly where you are running this code? is it like any azure environment like vm? – JayashankarGS Commented Mar 17 at 9:50
  • @JayashankarGS The App runs on Databricks clusters, which I think are composed of Azure Virtual Machines (VMs) and managed resources. – Obirieni Simeo Commented Mar 18 at 10:13
Add a comment  | 

1 Answer 1

Reset to default 0

The DefaultAzureCredential() tries to fetch the credential in following order, it stops once it gets any one of the credentials.

  • EnvironmentCredential
  • WorkloadIdentityCredential
  • ManagedIdentityCredential
  • SharedTokenCacheCredential
  • VisualStudioCredential
  • VisualStudioCodeCredential
  • AzureCliCredential
  • AzurePowerShellCredential
  • AzureDeveloperCliCredential
  • InteractiveBrowserCredential

So, if it's in azure hosted environment then enable the managed identity.

If it's service principal, then configure below environment variables like mentioned here

AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET

Make sure you assign required roles to your managed identity or service principal in sql server resource.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论