Many ABL applications authenticate a user identity externally. For user identities that are asserted in an authentication-enabled domain, you can authenticate and set a session identity directly from an unsealed client-principal using the SECURITY-POLICY:SET-CLIENT( ) method. OpenEdge then performs the user authentication, (if successful) seals the client-principal, and sets the session identity, all in a single operation.
Using a client-principal object with the session domain registry and appropriate database configuration options, you can set any authenticated user identity as the ABL session identity, which OpenEdge can then recognize for use with various OpenEdge features. For example:
If you select the database option (using Data Administration tools), Use Application Domain Registry, OpenEdge uses the current session registry (instead of the local database domain registry) for authenticating and validating any user identity assigned to the database connection, including the ABL session identity. In this way, the database can authorize access to its tables and fields based on the effective ABL session identity. If all connected OpenEdge databases are configured to use the application domain registry, you can efficiently set all of their database connection identities to this single ABL session identity. Thus, you can use the ABL session identity to synchronize all user identities for the entire ABL session.
If you select the database option, Use Application User Id for Auditing, the database records the ABL session user ID as the auditing ID in its audit event records.
Note: Set the database option, Use Application User Id for Auditing, only if you are individually managing the database connection identity for each database (see Establishing database connection identity ). If you synchronize all database connection identities with the ABL session identity, all connected databases use the ABL session user ID as the auditing ID by default.
You can set a single ABL session identity and use a copy of the sealed client-principal to transport this user identity between OpenEdge sessions of a distributed application to maintain a consistent identity among them (see Establishing and managing identity for multi-tier applications).
If you want to set an ABL session identity from a user identity that you authenticate externally, you must have a corresponding domain entry registered in the session domain registry. As described in an earlier section (see Setting up and using domain registries), you can build this registry within the ABL session at run time entirely from a local database domain registry or you can build it one domain entry at a time directly from ABL code. It is generally easier and more secure to load the session domain registry from a local database domain registry.
Any user ID that you authenticate with an OpenEdge-supported authentication system has an OpenEdge-supported functional identity after you validate that identity against the corresponding authentication domain. This you must do using a client-principal object.
To authenticate an ABL session identity:
1. Build the session domain registry using methods of the SECURITY-POLICY system handle (typically done at session startup).
2. Input the required user credentials, including an indication of the security domain and a passphrase (example).
3. Create and initialize a client-principal object with appropriate values associated with the input user credentials to set the object USER-ID, DOMAIN-NAME, SESSION-ID, and any other attributes or application properties (using the SET-PROPERTY( ) method.)
4. If the user's domain is authentication-enabled, authenticate the user's identity asserted with the client-principal using the SECURITY-POLICY:SET-CLIENT( ) method. Otherwise, proceed to step 6.
5. If the authentication succeeds, the asserted identity is now the session identity. If the authentication fails, the client-principal object is set to the FAILED state. Exit these steps accordingly.
6. If the user's domain supports application-performed authentication, authenticate the required user credentials using the specified external authentication system.
7. If the authentication succeeds, proceed to Step 8. If the authentication fails, invalidate the client-principal object with the AUTHENTICATION-FAILED( ) method and exit these steps accordingly.
8. Seal the client-principal object using the domain access code configured for the security domain in the session domain registry, starting a user login session for the identity the object represents.
Note: The authenticated identity has not yet been assigned to any resource yet.
9. Assert and validate the user identity represented by the client-principal object in an SSO operation for the database connection using the ABL SET-DB-CLIENT function. The SET-DB-CLIENT function validates the client-principal object against the database trusted domain registry in order to set the corresponding database connection identity. Optionally, you can invoke SET-DB-CLIENT without specifying a database connection and OpenEdge validates and (if valid) sets the identity against the database trusted domain registry for each active database connection in the session.
10. Assert and validate the authenticated user identity represented by the sealed client-principal object in SSO operation for the ABL session using the SECURITY-POLICY:SET-CLIENT( ) method. The SET-CLIENT( ) method validates the client-principal object against the session domain registry in order to set the ABL session identity.
In addition, for any existing database connections whose identities have not already been set using the SETUSERID or SET-DB-CLIENT functions, the SET-CLIENT( ) method also attempts to validate and set the connection identity in an SSO operation against the database trusted domain registry for each of these databases. This setting can always be overridden using the SETUSERID or SET-DB-CLIENT functions. However, if options for a given database are set to use the application domain registry, both SETUSERID and SET-DB-CLIENT use the session registry to validate and set the connection identity for that database.
Note: If the session domain registry is not initialized or remains unlocked, SET-CLIENT( ) does not validate an ABL session identity, but does validate the client-principal object and set database connection identities similar to the SET-DB-CLIENT function called without specifying a database connection (see Setting connection identity with application-performed userauthentication).
Thus, you might use a code fragment such as the following, which starts up an application-authenticated user login session in order to set an ABL session identity for an inventory application that accesses a single database (already connected). The bold-faced code features the user login session management and authentication elements, as shown:
Login session for an externally authenticated OpenEdge session ID
DEFINE VARIABLE cAccessCode AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPassword AS CHARACTER NO-UNDO.
DEFINE VARIABLE cUserID AS CHARACTER NO-UNDO.
DEFINE VARIABLE hAuthProc AS HANDLE NO-UNDO.
DEFINE VARIABLE hCP AS HANDLE NO-UNDO.
/* Declare external authentication functions */
FUNCTION authenticateMyUser RETURNS LOGICAL
(INPUT cUserID AS CHARACTER, INPUT cPassword AS CHARACTER) IN hAuthProc.
FUNCTION getAccessCode RETURNS CHARACTER IN hAuthProc.
/* Build the application trusted domain registry from the database domain
registry available for the single database connection */
SECURITY-POLICY:LOAD-DOMAINS(1).
/* Get user ID/password and instantiate external authentication object,
which also provides the authentication domain access code */
...
cUserID = ...
cPassword = ...
RUN MyAuthentication.p PERSISTENT SET hAuthProc. cAccessCode = getAccessCode().
/* Create and initialize a client-principal for use with an authentication
domain in the application domain registry */
CREATE CLIENT-PRINCIPLE hCp. ASSIGN
hCP:SESSION-ID = "Inventory:" + cUserID + STRING(NOW) hCP:USER-ID = cUserID hCP:DOMAIN-NAME = "InventoryApp".
/* Authenticate and login OpenEdge session ID for the application */
If authenticateMyUser(cUserID, cPassword) THEN DO:
hCP:SEAL(cAccessCode). /* Assert and validate ID against application domain registry */
IF NOT SECURITY-POLICY:SET-CLIENT(hCP) THEN DO:
hCP:LOGOUT(). cRetVal = "User ID not valid OpenEdge session ID".
END.
END.
ELSE DO:
hCP:AUTHENTICATION-FAILED("User not authenticated."). cRetVal = hCP:LOGIN-STATE + ": " + hCP:STATE-DETAIL. END.
/* Handle results of authentication */
IF hCP:LOGIN-STATE = "LOGIN" THEN DO: /* Do Inventory stuff... */
...
/* Clear the OpenEdge session ID to end the login session */
hCP:LOGOUT(). DELETE OBJECT hCP. END.
ELSE DO: /* Exit with failure message */
RETURN cRetVal.
DELETE OBJECT hCP. END.
In this fragment, the domain access code used by the application is maintained and returned by the same authentication procedure (MyAuthentication.p) that authenticates the user identity. This value, returned using the getAccessCode user-defined function, must match the access code configured for the authentication domain entry in the session domain registry.
Also in this code fragment, the setting of the SESSION-ID attribute, which includes the value of STRING(NOW), while valid is not necessarily unique. If you enable auditing for the application, where unique references are more important, use the GENERATE-UUID function (or for a multi-tier application, the client context ID) to set the SESSION-ID attribute. For more information, see Creating and managing unique object identities .
Note: If no database connection identity is set for the connected database, the SET-CLIENT( ) method in this fragment also sets the database connection identity, by default, using the database's own trusted domain registry. If database options are set to trust the application domain registry, SET-CLIENT( ) uses the session domain registry (which in this example has the same content as the local database domain registry) to set the database connection identity. Also, if you replace SECURITY:SET-CLIENT(hCP) with SET-DB-CLIENT(hCP) in this code, the entire fragment only sets and manages the database connection identity, and the OpenEdge session identity is undefined.