Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

Vaadin 10 -> 14 : Logout with @Push -> relogin redirects to /vaadinServlet

Jorn De Pril
3 years ago Sep 24, 2019 12:21pm

Hi Community,

I have a question puzzling me where I would need some additional eyes to put me on the right track again.

Currently using Vaadin 14, Spring boot and Spring security 2.1.0 (but have tested with Vaadin 10 and 12 as well -> same behaviour).

WebSecurityConfig :
	http
		.csrf().disable()
		.authorizeRequests()
		    //.antMatchers("/vaadinServlet/**").permitAll() 
		    //.antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll()
		    //.antMatchers("/").permitAll()
		    .anyRequest().authenticated()
		    .and()
		.formLogin()
		    //.defaultSuccessUrl("/console")
		    .defaultSuccessUrl("/")
		    .permitAll()
		    .and()
		.logout()
		    //.logoutSuccessHandler(logoutSuccessHandler())
		    //.logoutSuccessUrl("/")
		    .permitAll();
		    //.invalidateHttpSession(true)
		    //.deleteCookies("JSESSIONID");

Problem description : After performing a logout and performing a relogin, the user is always redirected to a vaadinServlet push (blank) page. Either the user needs to manually change the URL in the address bar (to see the application again) or i need to close the browser session and reopen one to relogin. If i disable the @Push command, then the logout/login is behaving fine. This behaviour is only reproducible with @Push set on the mainlayout.

Steps to reproduce :

1. Login to the application -> redirected to / with authenticated user
2. Press the logout button -> redirected to /login again 
3. Relogin to the application -> redirected to /vaadinServlet/?v-r=push&v-uiId=0&v-pushId=61d5b1bd-bdfc-467d-8edc-65850b6c1e56&X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=090400fe-2161-4e65-aed2-6b7cf479bf5c&_=1569327047300   with authenticated user

Wanted behaviour : On second login, just go to the mainpage / and not redirect to /vaadinServlet/?v-r=push..............

My very cluttered logout section because i have tried tons of stuff :

// Redirect this page immediately
		SecurityContextHolder.clearContext();
		VaadinService.getCurrentRequest().getWrappedSession().invalidate();
		
		// Hack to turn off PUSH on all UIs first. Doing it this way to try to avoid spurious PUSH sessions reactivating.
		    for( final UI ui : VaadinSession.getCurrent().getUIs() ) {
//			ui.access((Command) new Runnable() {
//			    @Override
//			    public void run() {
//				ui.getPushConfiguration().setPushMode(PushMode.DISABLED);
//			    }
//			});
			
			ui.access(new Command(){
			    @Override
			    public void execute() {
				LOGGER.info(String.format("DISABLE PUSH :  %s", ui.getPage().getClass().toString()));
				ui.getPushConfiguration().setPushMode(PushMode.DISABLED);
			    }

			});
		    }

		    // Force all UIs to be logged off when any UI logs off
		    for( final UI ui : VaadinSession.getCurrent().getUIs() ) {
			ui.access(new Command(){
			    @Override
			    public void execute() {
				LOGGER.info(String.format("SET LOCATION FOR :  %s", ui.getPage().getClass().toString()));
				ui.getPage().setLocation("/");
			    }

			});
//			ui.access((Command) new Runnable() {
//			    @Override
//			    public void run() {
//				if ( ui instanceof EsfVaadinUI ) {
//				    EsfVaadinUI vui = (EsfVaadinUI)ui;
//				    vui.setLogoffUrlNormal();
//				    vui.getPage().setLocation(logoutUrl); // set the logoff page before we close the session
//				}
//			    }
//			});
		    }
		
		
		getUI().get().getPage().executeJs("window.location.href='logout'");
		//getUI().get().getPage().setLocation("/");
		// Close the session
		LOGGER.info(String.format("KOM IK HIER NOG IN SESSION CLOSE ?"));
		getUI().get().getSession().close();
		getUI().get().getPage().setLocation("/");

Questions that I have :

1. Am i supposed to redirect the user request ? Am i supposed to close any PUSH related sessions ?
2. Do I need to execute some commands in some specific order ?
3. Is there somebody willing to explain me in detail the logout logic in relation to Atmosphere ?
4. Should I take another approach ?
5. Is there any documentation out there that i just need to read to find the answer ?

Similar related issues that i found but have not revealed a solution to me :

https://vaadin.com/forum/thread/7885028

https://vaadin.com/forum/thread/15871148/spring-security-vaadin-push

https://vaadin.com/forum/thread/17348774/logout-invalidate-session-causes-session-expired-when-push-is-enabled

Regards,

Jorn

Last updated on Sep, 24th 2019
Jorn De Pril
3 years ago Nov 30, 2019 4:23pm
Leif Åstrand
3 years ago Dec 02, 2019 8:20am

The suspected underlying issue that I had in mind was https://github.com/vaadin/flow/issues/4071 which was fixed in Flow 2.0.19 last week. This Flow version is not yet part of any Vaadin release (Vaadin 14.0.14 uses Flow 2.0.18).

We are planning to release Vaadin 14.0.15 including this fix today or tomorrow.

Leif Åstrand
3 years ago Dec 02, 2019 8:54am
Jorn De Pril
3 years ago Dec 09, 2019 4:58pm
Leif Åstrand
3 years ago Dec 10, 2019 7:48am
Jorn De Pril
3 years ago Dec 10, 2019 3:15pm
hatyga fatyh
3 years ago Dec 16, 2019 6:53pm
Bartosz Śmigielski
3 years ago Dec 18, 2019 6:12pm

I have encountered same issue, depending on https://stackoverflow.com/questions/34364802/spring-prevent-ajax-call-from-being-target-url-on-authentication i made this piece of code as workaround but I can't guarantee that there is no side effects.

public class CustomRequestCache extends HttpSessionRequestCache { 

   @Override
   public void saveRequest(HttpServletRequest request, HttpServletResponse response) {
       String parameter = request.getParameter("X-Atmosphere-Transport");
       if (parameter == null || !parameter.equalsIgnoreCase("close") ) {
           super.saveRequest(request, response);
       }
   }
}

and then simply set it in WebSecurityConfigurerAdapter

	@Bean
   public RequestCache requestCache() {
       return new CustomRequestCache();
   }

    @Override
   public void configure(HttpSecurity http) throws Exception {
       http.
               requestCache().requestCache(requestCache())

Seems working in my case.

Last updated on Dec, 18th 2019
Jorn De Pril
3 years ago Dec 19, 2019 9:03am