Programmatically use Safe User ID
- Last Updated: October 30, 2020
- 4 minute read
- OpenEdge
- Version 12.2
- Documentation
In multi-tenant applications, one of the operations that always happens at the beginning of a client request is to establish the identity of a tenant user in the database connection. As a best practice, you do this by setting a valid user identity in the ABL application's Activate event procedure. OpenEdge does not support the ability to programmatically change the safe user identity for a database. The use of the Safe User ID feature does not require any modification to the ABL code. However, as a best practice, you should insert code into the ABL application's Activate event procedure to do the following:
- Check whether the database connection is locked
- Determine whether the current user identity of a database connection user is the safe user
These capabilities are useful when, in the midst of the business application execution, you need to verify whether the database connection is available. A locked database connection indicates that that safe user has failed to be authenticated, which normally requires remediation within the ABL application. The best place to check for database connection authentication failures is in the Activate event procedure.
The following topics describe the behavior that the safe user ID feature, if configured in the multi-tenant database, has on the Activate and Deactivate procedures in the ABL application.
How Safe User ID is used in the request life cycle
It might be useful to consider that a client request life cycle has three phases: activation, execution, and deactivation. With regards to asserting the safe user identity, you might design the ABL application to participate in that cycle in either the Activate or Deactivate procedures. It depends on what makes the most sense for your ABL application.
Note that coding the Activation and Deactivation event procedures in an ABL application is optional. The Safe User ID feature will ensure that tenant data is protected regardless. However, it is a best practice to implement these procedures in a multi-tenant application. The best practice is always to implement an Activate procedure, and before a client request is executed, to ensure in the Activate procedure that the database connection is not locked.
Safe User ID lockout policy
The main cause of tenant data bleed is when the ABL application fails to handle an authentication error while setting a database connection's user identity. By default, the AVM does not clear the previous user identity from the database connection. In the case of an authentication error, this default behavior permits the ABL business logic to continue and assume that the database's security is operating with the new user identity. Setting the safe user identity changes this default behavior by re-asserting the safe user identity either before or after a client request is accepted. If the authentication of a new client user fails, and a safe user identity is configured on the database, the available connection becomes automatically set to the safe user and tenant data access is prevented.
When a failure occurs in setting the database connection's user identity to the safe user identity, the safe behavior is to prevent the ABL business application from having access to anything in the database until a viable safe user or tenant user identity has been validated and set in the connection. To provide this safe behavior, the Safe User ID feature locks out the database connection from any access to the database by any user identity, in the event of an authentication failure of the safe user identity.
To detect whether a database connection is in lockout mode, you can invoke the
GET-SAFE-USER() method. If the method returns
the UNKNOWN ( ? ) value, then the database
connection's user identity is in an indeterminate state and the database connection
is locked.
To unlock a database connection and resume operations requires that one of the following operations complete successfully:
- Use the
SET-DB-CLIENT()method and successfully authenticate a user identity in the database connection. - Use the
SETUSERID()method and successfully authenticate a user identity in the database connection. - Use the
SET-CLIENT()method on the SECURITY-POLICY system handle and successfully authenticate a user identity in the database connection (note thatSET-CLIENT()lockout policies apply). - Use the
GET-SAFE-USER()method to get a copy of the sealed client-principal object that represents the safe user identity. - Use the
SET-SAFE-USER()method as part of exception handling, whereby if you have a critical failure in the ABL application, you may set the safe user identity to prevent the application from having access to tenant data. - Disconnect the database and reconnect it to renew the safe user identity from a fully authenticated database user.
How to check for a locked database connection
When the Safe User ID feature is enabled on a multi-tenant database, you should
design the ABL application to check for a locked database connection before
processing a client request. A best practice is to do this check within the Activate
event procedure by implementing the GET-SAFE-USER() method. If this
method returns a value showing that the connection is locked, the likely cause is an
authentication failure of the safe user. In the event of such a failure, you can
insert code that resets the database connection user to a valid user, because you do
not want to permit access to the database otherwise. For more information, see GET-SAFE-USER() method in ABL
Reference.