Hi again, the answer was way easier than I thought.
In session scope, I have a User object which contains details of the currently-logged-in user. (This object is also used to initially populate the Roles of the Identity object at user login.)
When the administrator clicks the 'emulate user' button, we simply replace the User object with a new one which has been retrieved from the database using a method which doesn't require a password. We then remove all roles Roles from the Identity object and (re)populate them using the new User object.
Although the new User object has a new integer ID, the session ID remains the same so good for auditing.
What kind of audit information do you capture when you emulate a different user. Do you also capture information on what kind of objects were modified when the admin emulated this user.
We simply capture the SQL being invoked against the database in regular .log files. Although this is cryptic to the untrained user, our operations staff would find everything they need to perform forensics should the need arise.
In more detail, we use a custom DAO layer (homegrown, not EJB3/JPA) and we enforce that the currently logged-in integer user ID, and session ID are passed as parameters whenever we invoke the database. Although the integer user ID changes when we 'emulate user', the session ID remains the same, so we can track the actions of any potentially evil administrators.