I have set up an application server with sparkle that supports several http requests and remoteDB. For authentification I use JWT.
I would like to use data from the JWT when logging into the database for setting session-variables in the DB Firebird) for using in triggers (user, machine, ip-address) for the audit trail.
I read a lot about switching off remoteDB authentication by setting password and user to "" but I just do not manage to access the jwt credentials when creation the database connection.
Would you mind supplying an approach to create a remoteDB module for sparkle using JWT authentication (JWT middleware added to the module) and accessing its data when establishing the database connection?
I would like to provide some more details - excerpts from my source:
First I create an Indy Sparkle Server:
SServer := TIndySparkleHTTPServer.create(nil);
I created this method as a shorthand for adding modules (as I add some with and without authentification)
procedure AddModule(Module: THttpServerModule; WithJWT: boolean = true); begin Module.AddMiddleware(TCompressMiddleware.create); if WithJWT then Module.AddMiddleware(TJwtMiddleware.create(Serversecret)); SServer.Dispatcher.AddModule(Module); end;
Within ModLogin I verify the user against the database (I use one database user for all connections and check against credentials in the database) and return JSON containing error message or a valid JWT to the client.
Finally I create the remoteDBModule and activate the server:
DB := TRemoteDBModule.create('/db', TDBConnectionFactory.create(
function: IDBConnection begin Result := CreateDBConnection(...); end)); DBCritical.UserName := ''; DBCritical.Password := ''; AddModule(DB,true); SServer.Active := true;
All the modules work but the DB connection is available independently of the JWT in the header although I added the middleware.
Apart from that I would like to use data from the decoded JWT in CreateDBConnection(...); to set Firebird session-variables that are used in triggers.
procedure TDB.OnHttpClientCreate(Sender: TObject; Client: THTTPClient); begin // Allow self signed certificate (as we only use it for encryption) TWinHttpEngine(Client.Engine).BeforeWinHttpSendRequest := procedure(Handle: HINTERNET) var dwFlags: DWORD; begin dwFlags := SECURITY_FLAG_IGNORE_UNKNOWN_CA or SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE or SECURITY_FLAG_IGNORE_CERT_CN_INVALID or SECURITY_FLAG_IGNORE_CERT_DATE_INVALID; WinHttpCheck(WinHttpSetOption(Handle, WINHTTP_OPTION_SECURITY_FLAGS, @dwFlags, SizeOf(dwFlags))); end; // set the authentication JsonWebToken Client.OnSendingRequest := procedure(Req: THttpRequest) begin Req.Headers.SetValue('Authorization', 'Bearer ' + FJWT); end; end;
One alternative in inherited from TRemoteDBModule and override the CreateConnection method. There you have a parameter with the THttpServerContext object that contains Request.User info (from JWT).