Connect to Azure SQL Database using Microsoft Entra access token from Delphi using FireDAC

169 Views Asked by At

I have managed to obtain an OAuth 2 access token for authentication in Azure SQL Database. The token is definitely OK as I am able to connect using it from the Azure Portal Console. Now I want to use the token to connect from my Delphi application using FireDAC over ODBC 18. FireDAC does not support this authentication method natively, so I have tried to add this functionality myself by editing the SetupConnection in FireDAC.Phys.ODBCBase unit as follows:

type
  PAccessToken = ^TAccessToken;
  TAccessToken = packed record
     dataSize: DWORD;
     data: TBytes;
   end;
...
var
 A: PAccessToken = nil;
...
procedure TFDPhysODBCConnectionBase.SetupConnection;
const
  SQL_COPT_SS_ACCESS_TOKEN = 1256;

var
  lPrevIgnoreErrors: Boolean;
  size : DWORD;
  S : UnicodeString;
begin
  if ConnectionDef.HasValue(S_FD_ConnParam_Common_LoginTimeout) then begin
    // Old informix versions (at least 9.4 and less) do not support LOGIN_TIMEOUT
    lPrevIgnoreErrors := ODBCConnection.IgnoreErrors;
    ODBCConnection.IgnoreErrors := True;
    try
      ODBCConnection.LOGIN_TIMEOUT := ConnectionDef.AsInteger[S_FD_ConnParam_Common_LoginTimeout];
    finally
      ODBCConnection.IgnoreErrors := lPrevIgnoreErrors;
    end;
  end;

  if ConnectionDef.HasValue('AuthToken') then begin
    lPrevIgnoreErrors := ODBCConnection.IgnoreErrors;
    ODBCConnection.IgnoreErrors := True;
    try
      S := ConnectionDef.AsString['AuthToken'];
      size := Length(S)*2;

      if Assigned(A) then
       Dispose(A);

      New(A);
      A.dataSize := size;

      SetLength(A.data, A.dataSize);
      ZeroMemory(@(A.data[0]), A.dataSize);
      Move(S[1], A.data[0], A.dataSize);

      ODBCConnection.Lib.SQLSetConnectAttr(ODBCConnection.Handle, SQL_COPT_SS_ACCESS_TOKEN, SQLPointer(A), SQL_IS_POINTER);
    finally
      ODBCConnection.IgnoreErrors := lPrevIgnoreErrors;
    end;
  end;
end;

Unfortunately, trying to connect always returns the following error:

[FireDAC][Phys][ODBC][Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user ''

Has anyone an idea how to pass the access token properly?

0

There are 0 best solutions below