I was able to implement session expiration after inactivity as described in this topic.
However, the session expiration is not made apparent to the User until they attempt to perform some action. I have the requirement to alert the User that their session is about to expire at least 20 seconds prior to it happening and give them the opportunity to extend it. If they do not extend the session, I need to send them back to the login screen as soon as the session time limit is reached.
I’ve been doing a lot of research on this topic but have yet to find a valid solution. I attempted to implement the UserInactivity Vaadin add-on, but found it introduced errors when opening a new browser tab after closing one.
I also considered using a Timer on the MainWindow to check the UserSessionEntity’s LastUsedTs value and compare it against the current timestamp, but calls to the UserSessionService cause that value to be updated.
With either of these approaches, I still wasn’t sure how I would even handle redirection to the login page.
Does anyone have any experience implementing this type of functionality?
If session is about to expire it shows notification:
for (VaadinSession session : activeSessions) {
// obtain lock on session state
session.accessSynchronously(() -> {
if (session.getState() == VaadinSession.State.OPEN) {
// active app in this session
App app = App.getInstance();
// user is logged in and session is expiring
if (app.getConnection().isAuthenticated()
&& expiringSessions.contains(app.getConnection().getSessionNN().getId())) {
// notify all opened web browser tabs
List<AppUI> appUIs = app.getAppUIs();
for (AppUI ui : appUIs) {
if (!ui.isClosing()) {
// work in context of UI
ui.accessSynchronously(() -> {
new Notification("Your session is about to be closed", Type.TRAY_NOTIFICATION)
.show(ui.getPage());
});
}
}
}
} else {
closedSessions.add(session);
}
});
}
List of expiring sessions is obtained from the middleware using system session:
// obtain system session with all permissions
// check session timeout on behalf of this session
// it is required due to session prolongation on request
UserSession systemSession;
try {
systemSession = trustedClientService.getSystemSession(webAuthConfig.getTrustedClientPassword());
} catch (LoginException e) {
log.error("Unable to get system session");
return;
}
List<UUID> expiringSessions;
AppContext.setSecurityContext(new SecurityContext(systemSession));
try {
expiringSessions = sessionExpirationService.getExpiringSessions();
} finally {
AppContext.setSecurityContext(null);
}
If it is enabled Web Client closes the UIs and the session after the cuba.httpSessionExpirationTimeoutSec expires after the last non-heartbeat request.
Hi @JohnM,
No, unfortunately this change was put on hold due to shifting project priorities. I hope to get back to it soon, at which point I will post an update.
Hi @artamonov,
That is nice, I wish I were able to upgrade to one of those versions, since it seems so much easier to do what I need to do. I had to turn off heartbeat completely just to get my sessions to actually expire in version 6.6.4 (see Session Expiration Not Working - CUBA.Platform).
Hi @artamonov,
It appears that you are using a newer version of the framework than I have. We are using 6.6.4, and it does not have the TrustedClientService. Is there a similar service in this version of CUBA that I should be using instead?
@artamonov,
Thanks for the info! I used loginService#getSystemSession(), which seemed like a closer match to the TrustedClientService method used in the example code. I also had to recreate UserSessionsAPI#getUserSessionsStream(), which does not exist in this version either.
Unfortunately, I’ve run into another issue: AppStartedEvent is not available in 6.6.4. Do you know of an alternative approach that I can use in order to implement the functionality of AppExpirationWatcher#onAppStart()?
@artamonov,
That’s what I was afraid of… is there no other way to trigger the init functionality when the app starts up? Maybe overriding an OOB class to call the function explicitly instead of relying on events?
I’m operating under a very tight deadline, and my company purchased some support hours after I setup this topic, so I’m going to utilize some of those hours for this topic. Thanks for your help thus far!