I am struggling to get my Spring Security stuff working properly. The behavior I’m going for is to have my app logoff after the session expires, but for some reason I’m having so many problems. I’m using SystemMessagesProvider to display a message to the user and afterwards, redirect to a logout view.
When a session expires, a new one pops up right away, so the user is always logged on, which is not what I want at all. To compensate, I have my logout view log off and redirect to my “/”.
If someone has an elegant Vaadin 24 Spring Security solution that you wouldn’t mind sharing with me, I would so very much appreciate it. I’ve spent days spinning wheels with this. I’m open to try anything to get passed this.
Cheers! Thank you very much,
Clint
When the session times out, the messsage I intended is displayed: “Your session has expired. Click here to sign back in”
But, when you click, a message of “Internal error, Please notify the administrator” pops up, along with a null pointer exception in the logs with the message:
Cannot invoke “com.vaadin.flow.component.UI.getInternals()” because the return value of “com.vaadin.flow.component.UI.getCurrent()” is null
I’m pretty sure the the LogoutView’s call in onAttach to attachEvent.getUI().navigate(“/”) is the culprit.
Some of my code:
/**
* Customizes Vaadin system messages, specifically handling session expiration
* by redirecting the user to the home page.
*/
@Component
public class ExpiredAppSystemMessagesProvider implements SystemMessagesProvider {
@Override
public SystemMessages getSystemMessages(SystemMessagesInfo systemMessagesInfo) {
CustomizedSystemMessages messages = new CustomizedSystemMessages();
// Session expiration settings
messages.setSessionExpiredCaption("Your session has expired.");
messages.setSessionExpiredMessage("Click here to sign back in.");
messages.setSessionExpiredURL("/logout");
messages.setSessionExpiredNotificationEnabled(true);
return messages;
}
}
/**
* Configuration for Vaadin-specific settings.
* Registers the ExpiredAppSystemMessagesProvider to handle session timeout redirects.
*/
@SpringComponent
public class VaadinConfig implements VaadinServiceInitListener {
private final ExpiredAppSystemMessagesProvider systemMessagesProvider;
@Autowired
public VaadinConfig(ExpiredAppSystemMessagesProvider systemMessagesProvider) {
this.systemMessagesProvider = systemMessagesProvider;
}
@Override
public void serviceInit(ServiceInitEvent event) {
// Register the system messages provider to handle session timeout redirects
event.getSource().setSystemMessagesProvider(systemMessagesProvider);
}
}
/**
* View for handling user logout.
* This view automatically logs out the current user and redirects to the home page.
*/
@PageTitle("Logout")
@Route(value = "logout")
@RolesAllowed("USER")
public class LogoutView extends VerticalLayout {
private static final Logger logger = LoggerFactory.getLogger(LogoutView.class);
private final LogoutService logoutService;
public LogoutView(LogoutService logoutService) {
this.logoutService = logoutService;
}
@Override
protected void onAttach(AttachEvent attachEvent) {
super.onAttach(attachEvent);
// Call logout method
logoutService.logout();
attachEvent.getUI().navigate("/");
logger.info("User logged out and redirected to home page");
}
}
/**
* View for handling user logout.
* This view automatically logs out the current user and redirects to the home page.
*/
@PageTitle("Logout")
@Route(value = "logout")
@RolesAllowed("USER")
public class LogoutView extends VerticalLayout {
private static final Logger logger = LoggerFactory.getLogger(LogoutView.class);
private final LogoutService logoutService;
public LogoutView(LogoutService logoutService) {
this.logoutService = logoutService;
}
@Override
protected void onAttach(AttachEvent attachEvent) {
super.onAttach(attachEvent);
// Call logout method
logoutService.logout();
attachEvent.getUI().navigate("/");
logger.info("User logged out and redirected to home page");
}
}