Can Apex code tell if you are impersonating a user vs actually being logged in as that user?
Adding on to Daniel's post, there is a different class called SessionManagement that will return some, if not all of the AuthSession attributes for the current session. This way, you can determine the type of session for the current session.
Map<String,String> currentSessionAttributes = Auth.SessionManagement.getCurrentSession();
String sessionType = currentSessionAttributes.get('SessionType');
//If sessionType == 'SubstituteUser', act on logged-in-as user.
Details on the SessionManagement class can be found here.
No. As far as the code is concerned, the effective user is the user performing the action. Any records created by an administrator logged in as a user will have their createdby and lastmodifiedby audit fields set to that user, and userinfo.getuserid() will return the user being logged in as. This is the same behavior as System.runAs() in test methods, with the exception that code can detect if it is being run in a test method. There's nothing you can do, such as examining the session ID, etc, that would give you any clue at all, unless you know how to decrypt the session ID (hypothetically; presumably this is how the UI knows).
It's not foolproof, but querying the AuthSession looks promising.
Unfortunately, there doesn't appear to be an easy way to find the AuthSession records that correspond to the current SessionID - How can I find the AuthSession that corresponds with the current Session Id?
However, an impersonator will get AuthSession SessionType of SubstituteUser.
SubstituteUser
A session created when one user logs in via another user. For example, if an administrator logs in as another user, a SubstituteUser session is created. Source
They will also lack LoginHistoryId
, LoginType
, LogoutUrl
, and LoginGeoId
field values. The former is particularly interesting, as it shows they never really "logged in".
As a very rudimentary check from Apex:
List<AuthSession> authSession = [Select Id from AuthSession where UsersId = :UserInfo.getUserId() and SessionType = 'SubstituteUser'];
Boolean hasLoggedInUser = !authSession.isEmpty();
Of course, this won't handle cases where the actual user is also logged in at the same time. You could do some additional checks to see if there are other active sessions for the same UsersId
.
Alternatively, on the client side you could check for the presence of a RSID
cookie. If this exists then the current session is using the login as functionality.
Unfortunately you can't directly check for the presence of this cookie in Apex as it doesn't have the apex_
prefix. Maybe write a new Apex accessible cookie client side if RSID
is detected.