Managing user identities for a state-free application service
- Last Updated: February 11, 2026
- 2 minute read
- OpenEdge
- Version 13.0
- Documentation
In a state-free application service, the process of managing user identities is somewhat more complicated by the lack of any client connections. This requires the application service to manage user identities independently of any physical client identity and to provide a means to exchange the client's identity with the application service on every client request. Note, for a state-free AppServer like the Classic Application Server, there are no configurable connection and disconnection procedures. So, all the work of establishing and clearing user identities for a given client request must be done for each and every service call by the application service itself. However, this process is simplified using the client context ID mechanism that is available for both state-free and stateless application services. Following is a typical procedure for managing state-free user identities authenticated using application-performed user authentication together with this client context ID mechanism.
To manage users identities for a state-free application service:
- In the AppServer's configured startup procedure, build any required session domain registry and remove any client-principal objects from a previous user context left-over from any abnormal session termination.
- In the application service's login procedure:
- Initialize
and seal the client-principal object, including setting a unique
value for the
SESSION-IDattribute from theClientContextIdproperty on theProgress.Lang.OERequestInfoobject available through theSESSION:CURRENT-REQUEST-INFOattribute. - Export the client-principal object.
- Store the exported
RAWvalue of the client-principal object in a context database keyed on theSESSION-IDattribute value. - Return the
SESSION-IDattribute value (client context ID) as an output parameter to the client. The client will then call all non-login procedures of the application service by assigning this client context ID to theClientContextIDproperty on theProgress.Lang.OERequstInfoobject that is available through theREQUEST-INFOattribute on the server object handle for the application service.
For example:
DEFINE OUTPUT PARAMETER cSessionID AS CHARACTER NO-UNDO. DEFINE SHARED VARIABLE hCP AS HANDLE NO-UNDO. DEFINE VARIABLE cAccessCode AS CHARACTER NO-UNDO. DEFINE VARIABLE rCP AS RAW NO-UNDO. CREATE CLIENT-PRINCIPAL hCP. /* Initialize, authenticate, seal, and login client-principal object */ ... hCP:SESSION-ID = SESSION:CURRENT-REQUEST-INFO:ClientContextId. hCP:SEAL(cAccessCode). /* Export client-princpal object */ rCP = hCP:EXPORT-PRINCIPAL(). /* Store exported client-principal */ CREATE UserContext NO-ERROR. ASSIGN UserContext.Principal-key = hCP:SESSION-ID UserContext.Principal = rCP NO-ERROR. /* Return the client context ID value to client */ cSessionID = hCP:SESSION-ID. ... - Initialize
and seal the client-principal object, including setting a unique
value for the
- In all non-login procedures for the application service:
- Retrieve
the client context ID from the
ClientContextIDproperty on theProgress.Lang.OERequstInfoobject that is available through theSESSION:CURRENT-REQUEST-INFOattribute. - Lookup the exported client-principal object in the context database using the security token value as the lookup key.
- Import the client principal object.
- Validate the imported client-principal seal, and use the validated client principal object to set the user identity.
- Perform the application service task.
- Clear the ABL session identity for the next user.
For example:
DEFINE VARIABLE cSessionID AS CHARACTER NO-UNDO. DEFINE VARIABLE rCP AS RAW NO-UNDO. DEFINE SHARED VARIABLE hCP AS HANDLE NO-UNDO. cSessionID = SESSION:CURRENT-REQUEST-INFO:ClientContextId. CREATE CLIENT-PRINCIPAL hCP. /* Lookup client-principal object in context database */ FIND UserContext WHERE Principal-key = cSessionID NO-ERROR. rCP = UserContext.Principal. /* Import client-princpal object, validate, and set user identity */ hCP:IMPORT-PRINCIPAL(rCP). IF SECURITY-POLICY:SET-CLIENT(hCP) THEN /* Identity is valid */ ... /* Perform application service task */ ELSE /* Identity is not valid */ ... /* Clear user identity for next user */ hCP:LOGOUT(). DELETE OBJECT hCP. ... - Retrieve
the client context ID from the
- In the application service's logout procedure:
- Retrieve
the client context ID from the
ClientContextIDproperty on theProgress.Lang.OERequstInfoobject that is available through theSESSION:CURRENT-REQUEST-INFOattribute. - Lookup the exported client-principal object in the context database using the security token value as the lookup key.
- Remove the exported client-principal object from the context database.
For example:
DEFINE VARIABLE cSessionID AS CHARACTER NO-UNDO. cSessionID = SESSION:CURRENT-REQUEST-INFO:ClientContextId. /* Lookup client-principal object and remove from context database */ FIND UserContext WHERE Principal-key = cSessionID NO-ERROR. DELETE UserContext NO-ERROR. ... - Retrieve
the client context ID from the
- In the AppServer's configured shutdown procedure, empty the user
context database. For example:
/* Empty the context database */ FOR EACH UserContext: DELETE UserContext NO-ERROR. END. ...