ODATA authentification - handle EROSessionExpired exception


With TDAODataSchemaDispatcher how can handle EROSessionExpired exception?

If an data is invoked and Session is expired, OnLoginNeeded is not fired.

Best regards,
Tiberiu Stoicescu


Do you pass Authorization header ?

How I can reproduce your case?
can you describe what headers are set on each step, pls ?

for example

  • initial step, Authorization header is passed
  • second step - only clientid is passed


TDAODataSchemaDispatcher is connected by design only.

object dispODStocApi: TDAODataSchemaDispatcher
     Server = Server
     Path = '/StocApi/'
     Namespace = 'WebService'
     ServiceName = 'DataService'
     MaxRecords = -1
     HttpAuthLoginServiceName = 'LoginService'
     SessionManager = SessionManager

DataService is set with RequiredSession true.

For the test:

  • a set of data is requested from the web browser
  • the credentials are entered and the result appears.
  • wait until the server session expires (do not restart the server as this option works).
  • a new set of data is requested from the same page of the web browser.
  • the error occurs


I can’t reproduce this case: ODataSchemaDispatcherLoginNeeded is always fired.

note: I’ve tested with Firefox browser

The described problem persists and creates difficulties when accessing data through ODATA
Not as often as I wrote initially, but sometimes the EROSessionExpired exception is raised.

When the exception is raised the stack is thrown like this:

uROSessions.TROCustomSessionManager.FindSession((154071800, 62476, 2350, (64, 199, 14, 0, 64, 110, 68, 253)),False)
uDAODataDispatcher.TDAODataAuthenticationMapping.AcquireGuid('Basic QTgwNTNFNjkwMkNFNDM3OUFGQ0YyMzMwMzU0QTE5Q0M6Qjg5NkVCOTJBQThENEREM0E4NEFDRjM0NjRBOEFDOUI=')
uDAODataDispatcher.TDAODataSchemaDispatcher.Process(TIndyHTTPTransport($FD49353C) as IROHTTPTransport,TIndyHTTPTransport($FD493540) as IROHTTPRequest,TIPHTTPResponseHeaders($FD39F1D8) as IROHTTPResponse,$FD398890,$FD399390)
uROCustomHTTPServer.TROCustomHTTPServer.HandleExtendedDispatchers('/StocApi',TIndyHTTPTransport($FD49353C) as IROHTTPTransport,TIndyHTTPTransport($FD49353C) as IInterface,TIPHTTPResponseHeaders($FD39F1D8) as IROHTTPResponse,$FD398890,$FD399390)
uROBaseHTTPServer.TROBaseHTTPServer.ProcessRequest(TIndyHTTPTransport($FD49353C) as IROHTTPTransportEx,$FD398890,$FD399390,TIPHTTPResponseHeaders($FD39F1D8) as IROHTTPResponse)
:76427ba9 KERNEL32.BaseThreadInitThunk + 0x19
:77b8bd2b ntdll.RtlInitializeExceptionChain + 0x6b
:77b8bcaf ntdll.RtlClearBits + 0xbf

I think it has to do with the values put in
SessionManager.SessionDuration and SessionManager.SessionCheckInterval
Initially I use the values 15 for both members.

If I set the value for SessionManager.SessionDuration lower (which doesn’t really make sense) the exception is raised in the interval between them.

What else could I check?


if you have exception in TROCustomSessionManager.FindSession, you can catch it in SessionManager.OnException event.

As I understand, your request contains GUID from previous session in HTTP headers, try to not pass it.

What should I do in SessionManager.OnException?
In the TROCustomSessionManager.FindSession method, raising EROSessionExpired exceptions are outside the control of the SessionManager.OnException event

If I set the SessionManager in the DAODataSchemaDispatcher object to null, the authentication service is invoked every time and the problems seem to be solved.
Is this a correct approach?

I don’t know how this works, the problems occur when running queries from a web browser.


I was able to reproduce issue with this condition.

update uDAODataDispatcher.pas as

function TDAODataAuthenticationMapping.AcquireGuid(aID: UnicodeString): TGUID;
    if fOwner.SessionManager <> nil then begin
      if fOwner.SessionManager.CheckSessionIsExpired(Result) then begin  //added
        fOwner.SessionManager.DeleteSession(Result, True);               //added
        Result := EmptyGUID;                                             //added
        Break;                                                           //added
      end;                                                               //added

Logged as bugs://D19433.

bugs://D19433 was closed as fixed.