Keycloak Springboot/Vaadin SSO integration and Ui.navigate problem

I integrated https://vaadin.com/docs/latest/tools/sso/integrations/keycloak Keycloak SSO Kit and it works pretty well.

What I now want to achieve is, that some pages were secured and some not. For that I add @PermitAll to those which I want to secure and @AnonymousAllowed to them I dont want to be secured. Calling the routes directly via browser navigation works as intended. Keyloak redirect for @PermitAll pages is done, for @AnonymousAllowed not.

The problem I got is, navigating from one page to the other, using UI.navigate(route). When calling UI.navigate(ToASecuredPageWithPermitAll) from a page with @AnonymousAllowed to a page with @PermitAll I got the following info message:

`Could not navigate to ‘securedview’

Available routes:

securedview`

Clicking on “securedview” doesnt do anything. Just calling the route directly via browser provides the intended behavior. What I´d like to achieve is the same behavior as directly accessing secured page: Redirect to Keycloak login page.

@bountiful-duck, do you have the sso-kit-starter dependency added to your pom.xml?

No I haven´t, @practical-rat . For what is that needed?

I tried it and the setup is getting much more weird than before: My main route “” is redirected then to sso.vaadin.com although I haven´t configured anything like this. My other routes with @AnonymousAllowed are forcing a login login with my dedicated Keycloak now, althought they shoudlnt because of the annotation.

The docs page you are linking (https://vaadin.com/docs/latest/tools/sso/integrations/keycloak) is for setting up the SSO Kit with keycloack, assuming that the steps in the Getting Started guide are completed (https://vaadin.com/docs/latest/tools/sso/getting-started), and the most essential part of the SSO Kit (the part that simplifies integration with keycloack, among other SSO providers) is present through the sso-kit-starter dependency.

And to clarify, the SSO Kit is a commercial tool, for which you can request a trial license from https://pages.vaadin.com/acceleration-kit-trials.

Im sorry, @practical-rat I mixed up the documentation links as I read so much articles. I followed the description from Simon Martinelli and got this behavior: https://martinelli.ch/vaadin-oauth2-and-keycloak/

I found a possible solution:

Used UI.getCurrent().navigate(“securedPage”); for redirection which is not working and showing the “route not found” page.

UI.getCurrent().getPage().setLocation(“securedPage”); indeed is working and redirecting to Keycloak for login.

To be honest, dont know the differences that much to decide if this is bug or maybe lack of understanding from my side.

I’m wondering how you are changing from the anonymous page to the non-public page. I’m not sure if it’s related to keycloak or just how the Vaadin UI and the Spring session is handled.
Can you explain how you can reproduce the error?

For the record, navigate uses Vaadin’s internal navigation whereas setLocation essentially updates the address bar in the browser

Thanks for the explanation. Looks like this makes the difference. navigate doesnt trigger a complete http security flow and with that, keycloak is not triggered, while setLocation does.

Generally my integration is very fragile, or Im doing something completly wrong. Copied the working configuration from the now working project (A) to another (project B). Including spring-boot-starter-security and spring-boot-starter-oauth2-client in pom, same application.properties and the mentioned SecurityConfiguration and KeycloakLogoutHandler (working in project A) as described in the documentation. Added @AnonymousAllowed to the main route and got a complete different behaviour: The main route / is now secured (redirect to keyloak) although I annotated it with @AnonymousAllowed. Enabled the Springboot security logs by adding logging.level.org.springframework.security=DEBUG and see a complete different bahavior of the projects.

Working project A:
2023-08-21T21:21:27.289+02:00 DEBUG 13284 --- [nio-8083-exec-1] o.s.security.web.FilterChainProxy : Securing GET /MyRoute 2023-08-21T21:21:27.304+02:00 DEBUG 13284 --- [nio-8083-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext 2023-08-21T21:21:27.310+02:00 DEBUG 13284 --- [nio-8083-exec-1] o.s.security.web.FilterChainProxy : Secured GET /MyRoute 2023-08-21T21:21:27.410+02:00 INFO 13284 --- [nio-8083-exec-1] c.vaadin.flow.spring.SpringInstantiator : The number of beans implementing 'I18NProvider' is 0. Cannot use Spring beans for I18N, falling back to the default behavior 2023-08-21T21:21:27.538+02:00 DEBUG 13284 --- [nio-8083-exec-2] o.s.security.web.FilterChainProxy : Securing GET /VAADIN/build/indexhtml-51bec632.js 2023-08-21T21:21:27.538+02:00 DEBUG 13284 --- [nio-8083-exec-3] o.s.security.web.FilterChainProxy : Securing GET /VAADIN/build/index-ebbc34ab.css 2023-08-21T21:21:27.539+02:00 DEBUG 13284 --- [nio-8083-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext 2023-08-21T21:21:27.539+02:00 DEBUG 13284 --- [nio-8083-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext

Not working project B:
2023-08-21T21:20:13.440+02:00 DEBUG 12600 — [nio-8082-exec-1] o.s.security.web.FilterChainProxy : Securing GET /
2023-08-21T21:20:13.451+02:00 DEBUG 12600 — [nio-8082-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-08-21T21:20:13.511+02:00 DEBUG 12600 --- [nio-8082-exec-1] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:8082/?continue to session 2023-08-21T21:20:13.514+02:00 DEBUG 12600 --- [nio-8082-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], Not [And [Or [Ant [pattern='/login'], Ant [pattern='/favicon.ico']], And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@352f04d, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]]], org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer$$Lambda$929/0x0000000800686e18@6f15c146] 2023-08-21T21:20:13.515+02:00 DEBUG 12600 --- [nio-8082-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@2760b1de 2023-08-21T21:20:13.516+02:00 DEBUG 12600 --- [nio-8082-exec-1] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:8082/oauth2/authorization/keycloak 2023-08-21T21:20:13.522+02:00 DEBUG 12600 --- [nio-8082-exec-2] o.s.security.web.FilterChainProxy : Securing GET /oauth2/authorization/keycloak 2023-08-21T21:20:13.531+02:00 DEBUG 12600 --- [nio-8082-exec-2] o.s.s.web.DefaultRedirectStrategy : Redirecting to https://MYKEYCLOAKINSTANCE

Im wondering why the HttpSessionRequestCache is adding ?continue to my main route although I just called / in my browser. Maybe thats the issue this parameter/route might then be secured. But not sure if this is the issues, but nevertheless wondering why it adds the “?continue”.

Problem solved. Package structure was not appropriate