Embedding Calls in Middle-Tier Applications to Manage the Client Session ID
You can embed calls in middle-tier applications to manage client session IDs.
-
About Managing Client Session IDs Using a Middle-Tier Application
The application server generates the client session ID. -
Step 1: Retrieve the Client Session ID Using a Middle-Tier Application
When a user starts a client session, the application server generates a client session ID. -
Step 2: Set the Client Session ID Using a Middle-Tier Application
Next, you are ready to set the client session ID using a middle-tier application. -
Step 3: Clear the Session Data Using a Middle-Tier Application
The application context exists entirely within memory.
About Managing Client Session IDs Using a Middle-Tier Application
The application server generates the client session ID.
From a middle-tier application, you can get, set, and clear the client session IDs. To do so, you can embed either Oracle Call Interface (OCI) calls or DBMS_SESSION PL/SQL package procedures into the middle-tier application code.
The application authenticates the user, sets the client identifier, and sets it in the current session. The PL/SQL package SET_CONTEXT sets the client_identifier value in the application context.
Step 1: Retrieve the Client Session ID Using a Middle-Tier Application
When a user starts a client session, the application server generates a client session ID.
You can retrieve this ID for use in authenticating the user’s access.
-
To retrieve this client ID, use the
OCIStmtExecutecall with any of the following statements:-
SELECT SYS_CONTEXT('userenv', 'client_identifier') FROM DUAL; -
SELECT CLIENT_IDENTIFIER from V$SESSION; -
SELECT value FROM session_context WHERE attribute='CLIENT_IDENTIFIER';
-
For example, to use the OCIStmtExecute call to retrieve a client session ID value:
oratext clientid[31];
OCIDefine *defnp1 = (OCIDefine *) 0;
OCIStmt *statementhndle;
oratext *selcid = (oratext *)"SELECT SYS_CONTEXT('userenv',
'client_identifier') FROM DUAL";
OCIStmtPrepare(statementhndle, errhp, selcid,
(ub4) strlen((char *) selcid), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);
OCIDefineByPos(statementhndle, &defnp1, errhp, 1, (dvoid *)clientid, 31,
SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT);
OCIStmtExecute(servhndle, statementhndle, errhp, (ub4) 1, (ub4) 0,
(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);
printf("CLIENT_IDENTIFIER = %s \n", clientid);
In this example:
-
oratext,OCIDefine,OCIStmt, andoratextcreate variables to store the client session ID, reference call forOCIDefine, the statement handle, and theSELECTstatement to use. -
OCIStmtPreparprepares the statementselcidfor execution. -
OCIDefineByPosdefines the output variableclientidfor client session ID. -
OCIStmtExecuteexecutes the statement in theselcidvariable. -
printfprints the formatted output for the retrieved client session ID.
Step 2: Set the Client Session ID Using a Middle-Tier Application
Next, you are ready to set the client session ID using a middle-tier application.
-
About Setting the Client Session ID Using a Middle-Tier Application
After you use theOCIStmtExecutecall to retrieve the client session ID, you are ready to set this ID. -
Setting the Client Session ID Using a Middle-Tier Application
Oracle Call Interface or theDBMS_SESSIONPL/SQL package can set the client session ID using a middle-tier application. -
Checking the Value of the Client Identifier
For bothOCIAttrSetandDBMS_SESSION.SET_IDENTIFIER, you can check the value of the client identifier.
About Setting the Client Session ID Using a Middle-Tier Application
After you use the OCIStmtExecute call to retrieve the client session ID, you are ready to set this ID.
The DBMS_SESSION.SET_CONTEXT procedure in the server-side PL/SQL package then sets this session ID and optionally, overwrites the application context values.
You must ensure that the middle-tier application code checks that the client session ID value (for example, the value written to user_id in the previous examples) matches the client_id setting defined in the server-side DBMS_SESSION.SET_CONTEXT procedure. The sequence of calls on the application server side should be as follows:
-
Get the current client session ID. The session should already have this ID, but it is safer to ensure that it truly has the correct value.
-
Clear the current client session ID. This prepares the application to service a request from a different end user.
-
Set the new client session ID or the client session ID that has been assigned to the end user. This ensures that the session is using a different set of global application context values.
Setting the Client Session ID Using a Middle-Tier Application
Oracle Call Interface or the DBMS_SESSION PL/SQL package can set the client session ID using a middle-tier application.
-
Use either of the following methods to set the client session ID on the application server side:
-
Oracle Call Interface. Set the
OCI_ATTR_CLIENT_IDENTIFIERattribute in anOCIAttrSetOCI call. This attribute sets the client identifier in the session handle to track the end user identity.The following example shows how to use
OCIAttrSetwith theATTR_CLIENT_IDENTIFIERparameter. Theuser_idsetting refers to a variable that stores the ID of the user who is logging on.
-
OCIAttrSet((void *)session_handle, (ub4) OCI_HTYPE_SESSION,
(void *) user_id, (ub4)strlen(user_id),
OCI_ATTR_CLIENT_IDENTIFIER, error_handle);
- DBMS_SESSION package. Use the
DBMS_SESSION.SET_IDENTIFIERprocedure to set the client identifier for the global application context. For example, assuming you are storing the ID of the user logging on in a variable calleduser_id, you would enter the following line into the middle-tier application code:
DBMS_SESSION.SET_IDENTIFIER(user_id);
<div class="infoboxnote" markdown="1">
**Note:**
When the application generates a session ID for use as a `CLIENT_IDENTIFIER`, then the session ID must be suitably random and protected over the network by encryption. If the session ID is not random, then a malicious user could guess the session ID and access the data of another user. If the session ID is not encrypted over the network, then a malicious user could retrieve the session ID and access the connection.
You can encrypt the session ID by using network data encryption. See [Configuring Oracle Database Native Network Encryption and Data Integrity](oracle-database-native-network-encryption-and-data-integrity.html) for more information.
</div>
Checking the Value of the Client Identifier
For both OCIAttrSet and DBMS_SESSION.SET_IDENTIFIER, you can check the value of the client identifier.
-
To check the value of the client identifier, use one of the of the following approaches:
- To check it using the
SYS_CONTEXTfunction:
- To check it using the
SELECT SYS_CONTEXT('userenv', 'client_identifier') FROM DUAL;
- To check it by querying the
V$SESSIONview:
SELECT CLIENT_IDENTIFIER from V$SESSION;
Step 3: Clear the Session Data Using a Middle-Tier Application
The application context exists entirely within memory.
When the user exits a session, you must clear the context for the client_identifier value. This releases memory and prevents other users from accidentally using any left over values
-
To clear session data when a user exits a session, use either of the following methods in the middle-tier application code:
- Clearing the client identifier when a user exits a session. Use the
DBMS_SESSION.CLEAR_IDENTIFIERprocedure. For example:
- Clearing the client identifier when a user exits a session. Use the
DBMS_SESSION.CLEAR_IDENTIFIER;
- Continuing the session but still clearing the context. If you want the session to continue, but you still need to clear the context, use the
DBMS_SESSION.CLEAR_CONTEXTor theDBMS_SESSION.CLEAR_ALL_CONTEXTprocedure. For example:
DBMS_SESSION.CLEAR_CONTEXT(namespace, client_identifier, attribute);
The `CLEAR_CONTEXT` procedure clears the context for the current user. To clear the context values for all users, for example, when you need to shut down the application server, use the `CLEAR_ALL_CONTEXT` procedure.
Global application context values are available until they are cleared, so you should use `CLEAR_CONTEXT` or `CLEAR_ALL_CONTEXT` to ensure that other sessions do not have access to these values.