In a stateless application service, the process of managing user identities is somewhat simplified by the existence of client connections. Following is a typical procedure for managing stateless user identities authenticated using application-performed user authentication and the SESSION:SERVER-CONNECTION-ID attribute and the GENERATE-UUID function.

Note: A stateless application service can also manage user identities using the same client context ID mechanism that works for state-free application services. For more detailed information, see Managing user identities for a state-free application service.

To manage users identities for a stateless application service, you can do the following:

  1. 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.
  2. In the application service's login procedure:
    1. Initialize and seal the client-principal object using a UUID (to uniquely set any auditing context) as the value for the SESSION-ID attribute on the client-principal object.
    2. Export the client-principal object.
    3. Store the exported RAW value of the client-principal object in a context database keyed on the SESSION:SERVER-CONNECTION-ID attribute value.

    For example:

    DEFINE SHARED VARIABLE cAccessCode AS CHARACTER NO-UNDO.
    DEFINE SHARED VARIABLE hCP         AS HANDLE    NO-UNDO.
    
    DEFINE VARIABLE cSessionID AS CHARACTER NO-UNDO.
    DEFINE VARIABLE rCP        AS RAW       NO-UNDO.
    
    CREATE CLIENT-PRINCIPAL hCP.
    
    /* Initialize, authenticate, seal, and login client-principal object */
    ...
    cSessionID     = BASE64-ENCODE(GENERATE-UUID).
    hCP:SESSION-ID = SUBSTRING(cSessionID, 1, 22)
    hCP:SEAL(cAccessCode).
    
    /* Export client-princpal object */
    rCP = hCP:EXPORT-PRINCIPAL().
    
    /* Store exported client-principal by the connection ID */
    CREATE UserContext NO-ERROR.
    ASSIGN UserContext.Principal-key = SESSION:SERVER-CONNECTION-ID 
           UserContext.Principal     = rCP NO-ERROR.
    ...
  3. In the AppServer's configured activation procedure:
    1. Lookup the exported client-principal object in the context database using the SESSION:SERVER-CONNECTION-ID value as the lookup key
    2. Import the client principal object
    3. Validate the imported client-principal seal, and use the validated client principal object to set the user identity

    For example:

    DEFINE SHARED VARIABLE hCP AS HANDLE NO-UNDO.
    
    DEFINE VARIABLE rCP AS RAW NO-UNDO.
    
    CREATE CLIENT-PRINCIPAL hCP.
    
    /* Lookup client-principal object in context database */
    FIND UserContext 
      WHERE Principal-key = SESSION:SERVER-CONNECTION-ID 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 */
      ...
    ELSE /* Identity is not valid */
      ...
  4. In all non-login procedures for the application service, verify that the user identity is valid from activation procedure, and if it is, perform the specified application service task. For example:
    DEFINE SHARED VARIABLE cAccessCode AS CHARACTER NO-UNDO.
    DEFINE SHARED VARIABLE hCP         AS HANDLE    NO-UNDO.
    
    IF hCP:VALIDATE-SEAL(cAccessCode) THEN /* Identity is valid */
        ... /* Perform application service task */
    
    ELSE /* Identity is not valid */
        ...
  5. In the AppServer's configured deactivation procedure, clear the ABL session identity for the next user. For example:
    DEFINE SHARED VARIABLE hCP AS HANDLE NO-UNDO.
    
    hCP:LOGOUT().
    DELETE OBJECT hCP.
    ...
  6. In the application service's logout procedure:
    1. Lookup the exported client-principal object in the context database using the SESSION:SERVER-CONNECTION-ID value as the lookup key
    2. Remove the exported client-principal object from the context database, for example:
      /* Lookup client-principal object and remove from context database */
      FIND UserContext 
        WHERE Principal-key = SESSION:SERVER-CONNECTION-ID NO-ERROR.
      DELETE UserContext NO-ERROR.
      ...
  7. 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.
    ...