Skip to content

Blank Login View after navigating from @AnonymousAllowed to @PermitAll view #7296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
KasparScherrer opened this issue Apr 1, 2025 · 4 comments · Fixed by #7304
Closed

Blank Login View after navigating from @AnonymousAllowed to @PermitAll view #7296

KasparScherrer opened this issue Apr 1, 2025 · 4 comments · Fixed by #7304

Comments

@KasparScherrer
Copy link

Description of the bug

whenever I navigate programmatically from a @AnonymousAllowed view to a @PermitAll view (while not being authenticated yet), it redirects to the login view but it is completely blank (white, no content in the body except the outlet and the connection-indicator).

Meanwhile, when I navigate from a @AnonymousAllowed to a @PermitAll view by typing the url manually, the login view works fine and shows the login form. This difference makes me think the bug lies somewhere in UI::navigate maybe?

I can see a similar issue here vaadin/flow#20939 but for me there is no errors being shown, neither in server log nor in browser console.

This is how the LoginView HTML looks when the bug is happening:
Image

And this is how the LoginView HTML looks when it works properly:
Image

Expected behavior

The Login Form/Overlay should appear instead of a blank screen

Minimal reproducible example

Here are some views and configs that represent my setup:

@Route(value = "Test")
@AnonymousAllowed
public class TestView extends VerticalLayout {

    public TestView() {
        add(new Button("Navigate to authenticated view", click -> {
            UI.getCurrent().navigate(SomeAuthenticatedView.class);
        }));
    }

}
@Route(value = "authenticated")
@PermitAll
public class SomeAuthenticatedView extends VerticalLayout {

    public TestView() {
        add(new Span("You are authenticated."));
    }

}
@Route(value = "login")
@AnonymousAllowed
public class LoginView extends VerticalLayout {

    public LoginView() {
        LoginOverlay loginOverlay = new LoginOverlay();
        loginOverlay.setAction("login");
        loginOverlay.setOpened(true);
        loginOverlay.setI18n(prepareLoginI18N());
    }

}
@Configuration
@EnableWebSecurity
public class UiSecurityConfiguration extends VaadinWebSecurity {
    public static final String LOGIN_URL = "/login";

    public UiSecurityConfiguration () {
    }

    @Bean
    AuthenticationManager authManager(HttpSecurity httpSecurity, LogoutAuthenticationProvider logoutAuthenticationProvider) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder = (AuthenticationManagerBuilder)httpSecurity.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.authenticationProvider(logoutAuthenticationProvider);
        return (AuthenticationManager)authenticationManagerBuilder.build();
    }

    public void configure(HttpSecurity http) throws Exception {
        // this security config should only apply to paths that don't include /api/**
        http.securityMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/api/**")));
        http.authorizeHttpRequests((auth) -> {
            // allow images to be served
            ((AuthorizeHttpRequestsConfigurer.AuthorizedUrl)auth.requestMatchers((String[])this.getSecurityIgnoredPathsAndFiles().toArray(new String[0]))).permitAll();
        });
        this.setLoginView(http, LoginView.class, LOGIN_URL);
        super.configure(http);
    }

    private List<String> getSecurityIgnoredPathsAndFiles() {
        return Arrays.asList("/images/**");
    }
}

Versions

  • Vaadin / Flow version: 24.7.1
  • Java version: 17
  • OS version: Windows 11 Pro
@mcollovati
Copy link
Contributor

It looks like the problem is that OverlayAutoAddController.handleOpen removed the callback that adds the overlay to the UI in case of programmatic navigation.

if (event.getLocationChangeEvent()
.getTrigger() == NavigationTrigger.PROGRAMMATIC) {
addToUiRegistration.remove();
afterProgrammaticNavigationListenerRegistration
.remove();
}

I don't know whether this is a regression or the expected behavior, so I'll transfer the issue to flow-components repository for further investigation.

@mcollovati mcollovati transferred this issue from vaadin/flow Apr 8, 2025
@KasparScherrer
Copy link
Author

KasparScherrer commented Apr 9, 2025

Thank you for looking into it. That code snippet indeed looks like the culprit of my issue.
Whether or not this is expected behaviour I don't know of course, but if it is, please make it possible for the developer to opt out of this behaviour.
As it is now, I cannot make use of any @AnonymousAllowed view at all, except the loginview. Which is sad, because I really like the idea to have some views authenticated while other views are public. Currently, the user is presented with a white screen upon navigation, and while reloading the page would fix the issue for that session, I cannot expect my users to know that, and even if they did, that would be very unappealing UX.

@mcollovati
Copy link
Contributor

mcollovati commented Apr 9, 2025

Not 100% sure if it works, but as a work-around you can try to add the overlay explicitly to the LoginView

    public LoginView() {
        LoginOverlay loginOverlay = new LoginOverlay();
        loginOverlay.setAction("login");
        loginOverlay.setOpened(true);
        loginOverlay.setI18n(prepareLoginI18N());
        add(loginOverlay);
    }

@KasparScherrer
Copy link
Author

Yes that actually works! Thanks for finding that workaround.

In the meantime I have found in this commit that the LoginOverlay already had similar code within LoginOverlay::ensureAttached before the unified OverlayAutoAddController was used, but there it was only executed when getElement().getNode().getParent() == null. Not sure if that matters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants