VaadinSession attributes getting nulled / lifecycle question

Hi,

I have two Vaadin 14 Applications: LoginApp (running on localhost:8082) and SecuredContentApp (running on localhost:8083).

LoginApp does only contain a form where a user can enter credentials. After a successful login the Application directs to the SecuredContentApp. It calls a URL including a jwt token as a query parameter (UI.getCurrent().getPage().executeJs("window.open(\"http://localhost:8083?token=" + token + "\" , \"_self\");")).

That works pretty fine.

My plan was to take that token from the QueryParam and write it into the session. So that whenever SecuredContentApp is communicating with the backend service, it can take the token from the session and query the backend together with an authorization header containing the token.

I used VaadinServiceInitListener#serviceInit for taking the token from query param and saving it into the session. It works fine at first.

The Problem is: After the successful login after some seconds (sometimes directly, sometimes after a few seconds, sometimes after a lot of seconds) the token in the session becomes null and so the user is redirected to the LoginApp.

My InitListener class looks like that

@Service
public class ConfigureUIServiceInitListener implements VaadinServiceInitListener {

	@Autowired
	private HostnameConfiguration hostnameConfig;

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

	private void beforeEnter(BeforeEnterEvent event) {
		if (SecurityUtils.isFrameworkInternalRequest(VaadinService.getCurrentRequest())) {
			System.out.println("ignored internal request");
			return;
		}
		QueryParameters queryParameters = event.getLocation().getQueryParameters();
		if (queryParameters.getParameters().containsKey("token")) {
			System.out.println("token was set: "+ queryParameters.getParameters().get("token").get(0));
			VaadinSession.getCurrent().setAttribute("token", queryParameters.getParameters().get("token").get(0));
			UI.getCurrent().getPage().getHistory().replaceState(null, event.getLocation().getPath());
			return;
		}
		if (VaadinSession.getCurrent().getAttribute("token") == null) {
			System.out.println("token was null, returning to login app");
			UI.getCurrent().getPage().executeJs("window.open(\"http://localhost:8082\" , \"_self\");");
		}
	}

and the console output looks like:

token was set: eyJ..............................................................
token was null, returning to login app

I do not get why the token attribute inside the session becomes null, I absolutely don’t set it manually to null anywhere. And I don’t even do another request or something. I don’t even understand why the beforeEnter method is triggered a second time (resulting in “token was null, returning”).

Does anyone have an idea what is going on here? Do I follow the wrong approach here?

I just want to take the token one time from the query parameter and save it ANYWHERE where it doesn’t get lost for the user’s session so that I can send it to the backend when using the backend service (So yes, I want to use Vaadin only for UI-purposes. The token is just used when calling the backend service to get data. My idea was to have nearly no token validation in my SecuredContentApp directly…the only two checks should be:

  • Is the token saved inside the session? If yes, stay inside SecuredContentApp, if not: Obviously the SecuredContentApp-URL was called manually (using the login form assures that the SecuredContentApp is entered with a token query param which is saved into the session) → redirect to login
  • Does the backend service respond with 401? If not: everything is good. If yes, redirect to login.

As you see I don’t want any authentication/authorization code in my SecuredContentApp. I just want to save the token anywhere and check if it: is there and the BackendService accepts it and I don’t get the first point done as the token in the session always becomes null for some reason.

Thank you very much for any idea.

Hi,

it’s possible that the session of the first server is invalidated by the second because the cookie does not check the port ( only its name and the server name).

if you are running tomcat by default the cookie name is jsessionid and the host is localhost.

you can try by changing the host ( for example localhost:8082 and 127.0.0.1:8083), it’s quick and dirty :). you can also change the name of the cookie session. it’s clean but as I don’t know your setup i can’t give you the instructions to change it.

for example for spring boot server.servlet.session.cookie.name=

https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/html/common-application-properties.html

but maybe your problem is completely different :slight_smile: