#1 2020-12-14 04:31:29

missionhq
Member
From: Australia
Registered: 2019-06-11
Posts: 33

Can't override Ctxt.Call^.OutStatus in TSQLRestServer.OnSessionCreate

Hi,
I am trying to limit the number of concurrent client connections to my server by using TSQLRestServer.OnSessionCreate and returning true in order to abort the login attempt.
I also want to set Ctxt.Call^.OutStatus to something other than HTTP_FORBIDDEN (like HTTP_PAYMENT_REQUIRED smile) to let the client know it was a concurrent connection limitation rather than an invalid login attempt.

The problem I have is that when I do this, TSQLRestServer.SessionCreate in turn calls Ctxt.AuthenticationFailed(afSessionCreationAborted) which forces the OutStatus to HTTP_FORBIDDEN

procedure TSQLRestServer.SessionCreate(var User: TSQLAuthUser;
  Ctxt: TSQLRestServerURIContext; out Session: TAuthSession);
var i: PtrInt;
begin
  Session := nil;
  if (reOneSessionPerUser in Ctxt.Call^.RestAccessRights^.AllowRemoteExecute) and
     (fSessions<>nil) then
    for i := 0 to fSessions.Count-1 do
      if TAuthSession(fSessions.List[i]).User.fID=User.fID then begin
        {$ifdef WITHLOG}
        with TAuthSession(fSessions.List[i]) do
          Ctxt.Log.Log(sllUserAuth,'User.LogonName=% already connected from %/%',
            [User.LogonName,RemoteIP,Ctxt.Call^.LowLevelConnectionID],self);
        {$endif}
        Ctxt.AuthenticationFailed(afSessionAlreadyStartedForThisUser);
        exit; // user already connected
      end;
  Session := fSessionClass.Create(Ctxt,User);
  if Assigned(OnSessionCreate) then
    if OnSessionCreate(self,Session,Ctxt) then begin // TRUE aborts session creation
      {$ifdef WITHLOG}
      Ctxt.Log.Log(sllUserAuth,'Session aborted by OnSessionCreate() callback '+
         'for User.LogonName=% (connected from %/%) - clients=%, sessions=%',
        [User.LogonName,Session.RemoteIP,Ctxt.Call^.LowLevelConnectionID,
         fStats.GetClientsCurrent,fSessions.Count],self);
      {$endif}
      Ctxt.AuthenticationFailed(afSessionCreationAborted);     <===== This forces Ctxt.Call^.OutStatus to HTTP_FORBIDDEN
      User := nil;
      FreeAndNil(Session);
      exit;
    end;
  User := nil; // will be freed by TAuthSession.Destroy
  fSessions.Add(Session);
  fStats.ClientConnect;
end;

This is partly feedback for AB (thanks AB smile) but also looking for suggestions for a graceful way to fix this...

Offline

#2 2020-12-14 07:56:12

pvn0
Member
From: Slovenia
Registered: 2018-02-12
Posts: 209

Re: Can't override Ctxt.Call^.OutStatus in TSQLRestServer.OnSessionCreate

If you handle TSQLRestServer.OnAuthenticationFailed event you should be able to replace the OutStatus code, alternatively, SessionCreate is virtual so you can override it and do whatever you want.

Offline

#3 2020-12-15 03:49:57

missionhq
Member
From: Australia
Registered: 2019-06-11
Posts: 33

Re: Can't override Ctxt.Call^.OutStatus in TSQLRestServer.OnSessionCreate

Ah, sound like OnAuthenticationFailed is the way to go.
Cheers

Offline

Board footer

Powered by FluxBB