Disclaimer: I do not really understand fully, how Vaadin is wired to Spring security.
I have a requirement where banned users need to be gracefully kept out.
So I did the following.
- Downloaded a project with with authentication from the vaadin playground (https://start.vaadin.com)
- Modified the
User.javato includeprivate boolean banned = false;and the getter/setters - Modified the
UserDetailsServiceImpl#loadUserByUsernameto throw aDisabledExceptionif the user was banned
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("No user present with username: " + username));
if (user.isBanned()){
throw new DisabledException("You are banned");
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getHashedPassword(),
getAuthorities(user));
}
- Declared a @Bean in
SecurityConfiguration
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
- Injected
AuthenticationManagerinto theLoginView - Disabled
setActionin theLoginView - In the
LoginView, hooked up a login listener, to handle theDisabledExceptionby showing the user a feedback dialog, else it pass the buck
addLoginListener(loginEvent -> {
try {
var token = new UsernamePasswordAuthenticationToken(
loginEvent.getUsername(), loginEvent.getPassword());
var authResult = authManager.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authResult);
// Successful login → navigate to main view
UI.getCurrent().navigate("");
} catch (AuthenticationException authenticationException) {
//Check if this was caused by a DisabledException (banned user)
Throwable cause = authenticationException.getCause();
if (cause instanceof DisabledException) {
setOpened(false);
showDialog();
} else {
setI18n(LoginI18n.createDefault());
setError(true); // show error box
}
}
});
- Closing the dialog programatically logs out the user using
authenticatedUser.logout();which brings back theLoginView
Everything works fine as expected and the console is without any warning/error messages.
My question is: Is this the optimal way of handling this requirement or is there anything superior?
