Adding User realated data on Login

Hi,

i need to add some User specific data on login, to use those data (IDs etc) in some views. For example can a user belong to a group etc.

I could add this data once the user is logged in to the Vaadin Session but also could add it to the JWT

   setStatelessAuthentication(http, new SecretKeySpec(Base64.getDecoder().decode(JWT_AUTH_KEY), JwsAlgorithms.HS256),"xxx", 86400);

is there any other best practice?

I suppose the session is fine, at least without any additional knowledge of more specific requirements.

You mean with: VaadinSession.getCurrent().setAttribute(“mykey”,“myValue”);

when gets the Vaadin Session creted? After Login? I tried to add data to it during login but the VaadinSession then is null

Depends on how your login is implemented, but if you have a servlet filter based approach, it’s possible that the VaadinSession hasn’t been initialized yet when your login code is running, yes. Docs about the application lifecycle can be found here: https://vaadin.com/docs/latest/flow/advanced/application-lifecycle#application.lifecycle.session; note that you can e.g. add a listener for session initialization.

Thank you, using Spring Security with VaadinWebSecurity and JWT as well

We’re doing it similar…

In Main View we use the beforeEnterEvent to get the user to put it as Session variable

@Override
public void beforeEnter(BeforeEnterEvent event) {
	Optional<User> optUser = authenticatedUser.get();
	if (optUser.isPresent()) {
		User authUser = optUser.get();
		SessionBuilding.setSessionSettings(authUser);
		....

as we use users role etc. in other views.

And we add some of that information also into the header, defined in MainView like

	Optional<User> optUser = authenticatedUser.get();
	if (optUser.isPresent()) {
		User user = optUser.get();
		userLabel.setText(user.getPermission() + " " + user.getLastName());
		headerComponent.add(userLabel);
	}

AFAIR in this place we get the user not from session because we also had troubles with that, but it’s long ago.

Cheers
Mojo

Ah yeah in MainView that makes a lot of sense! Thank you

I have added it now at so it only happens once the user logs in and not on every navigation. Is there anything against this?

@Component
public class ConfigureUIServiceInitListener implements VaadinServiceInitListener {

    UserRepository userRepository;

    public ConfigureUIServiceInitListener(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public void serviceInit(ServiceInitEvent event) {
        event.getSource().addUIInitListener(uiEvent -> {
            final UI ui = uiEvent.getUI();
            ui.addBeforeEnterListener(this::beforeEnter);
            setUserToSession();
        });
    }

    private void beforeEnter(BeforeEnterEvent event) {
        if (!SecurityUtils.isAccessGrantedToView(event.getNavigationTarget())) {
            event.rerouteTo(AccessDeniedView.class);
        }
    }

    private void setUserToSession() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && !(authentication instanceof AnonymousAuthenticationToken)) {
            String username = authentication.getName();
            SessionService.setId(String.valueOf(userRepository.findIdByCustomerNumber(Integer.parseInt(username))));
        }
    }
}

The UI lifecycle is bound to a single browser tab while the session is shared between all the tabs in a browser instance. You should see this easily by adding a debugger breakpoint or a log statement in e.g. setUserToSession and opening two tabs in the same brower to this app. Make sure there aren’t any cases where a user might gain elevated privileges by logging in from two different tabs.

Ah yeah indeed its called per browser tab, then its not a good solution. Where would it be the best place to add it to the session once when i user Spring Security? Before login is to early, after login is too late ;)

I will try to add this into the @Override public UserDetails loadUserByUsername(String customerNo) {} from UserDetailsService