Vaadin 24 redirect to existing view gives the handleRpc error

I got view at /menu route annotated with @Component and @Scope(“session”) and user has to be athorized to view it.
I also have view at root “/” route which checks if user is already authorized and if yes then it redirects to the /menu view.
The redirect works but!
Problem is that sometimes when i repeatedly go to root url i get the
“Unexpected message id from the client. Expected sync 1, got 2. more details logged on DEBUG level.”

This is how i do redirect on the server side:
UI.getCurrent().executeJs(window.location.href=‘menu’)

Is there a way to prevent this handleRpc UnsupportedOperationException?

Two things:

  • scope session is to wide; it has to be ui or route (see docs)
  • why are you navigation with Javascript? Use UI::navigate

when changed to UI.getCurrent().navigate(“menu”) it is ending up in the BlackHole (implements HasErrorParameter)

Navigate has proper signature to use your class e.g. MyMenu.class

still nothing, ill add more context, the redirect gives com.vaadin.flow.route.NotFoundException without any details

That’s expected. (Security reasons) even tho that should not be the case… how is your view build?

its pretty simple view i think

`@Route(value = “menu”)
@UIScope
@Component
@PreserveOnRefresh
@CssImport(value = “./styles/my-styles.css”)
@PermitAll
public class MainMenu extends VerticalLayout {

private final Service service;

public MainMenu(Service service) {
this.service=service;
}

@PostConstruct
private void create() {
//adding some buttons that redirect to further modules
}
}`

Looks okay; only thing that comes to mind… the user isn’t authenticated and therefore it returns 404

Ye there is 401 returned for sw.js… this /menu view is my answer to SSO login. Before migrating to 24 when someone put root url he was immiedietaly redirected to ouath SSO url, then redirected back to root which was origanaly the menu. After migrating this approach stopped working, but i figured that redirecting user further to /menu makes the SSO work but now it seems like only the js redirection makes the SSO work and the UI.navigate does not… I probably have something wrong with the security config that for some reason it is not trying to authorize users…

is it possible to force authorization on root url which in my case is app.com/app ?

im ready to give up on the /app for server.servlet.context-path property, in fact i already tried it but nothing changed with the SSO

I have multiple apps integrated with external SSOs (e.g. keycloak) and there it should be enough to handle the direct in the authentication success handler of spring - therefore no hacking required and the user is really authenticated

will you be able to help me if i provided my http config?

Thats the config, it authorizes me at /app/menu, but not at /app/ (which is the root for my app)
adding request matcher for “/**” makes the authorization not work at all.

`Configuration
@EnableWebSecurity
public class KeycloakSecurity extends VaadinWebSecurity {
private final ResourceLoader resourceLoader = new DefaultResourceLoader();
final OidcUserService delegate = new OidcUserService();

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    http.headers(header -> header.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)));
    http
            .httpBasic(AbstractHttpConfigurer::disable)
            .formLogin(AbstractHttpConfigurer::disable)
            .anonymous(AbstractHttpConfigurer::disable)
            .csrf(AbstractHttpConfigurer::disable)
            .logout(logout -> logout
                    .logoutUrl("/sso/logout").permitAll()
                    .logoutSuccessUrl("/"))
            .oauth2Login(login -> login
                    .tokenEndpoint(endpoint -> endpoint.accessTokenResponseClient(getAuthorizationCodeToken()))
                    .userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig
                            .userAuthoritiesMapper(userAuthoritiesMapper())
                            .oidcUserService(userRequest -> {
                                OidcUser oidcUser = delegate.loadUser(userRequest);
                                ArrayList<String> roles = getRoles(userRequest);
                                Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
                                roles.forEach(e -> mappedAuthorities.add(new MyAuthority(e)));
                                oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), oidcUser.getUserInfo(), "preferred_username");
                                return oidcUser;
                            })));
}`

So many things… that’s a little bit much to digest…just an hint calling formLogin(disable) isn’t a good idea, because it activates stuff even tho you call disable

ok, thanks ill mess around with it to see if can figure it out