1

I have a simple Spring Boot web application consisting of 2 pages:

  • a Home Page (freely accessible) at the url https://example.com/
  • a secured page (requires login for being accessed) at the url https://example.com/secure/page.html

In the Home Page I'm printing the First Name of the visiting user (if he/she is already authenticated) or a sentence saying that the page is visited by an anonymous user.

I'm using Keycloak as far as authentication is concerned.

Here the Spring Security configuration:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    .authorizeRequests()
    .antMatchers("/secure/**")
    .authenticated()
    .and()
    .csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher())
    .and()
    .sessionManagement()
    .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
    .and()
    .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
    .addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
    .addFilterBefore(keycloakAuthenticatedActionsFilter(), BasicAuthenticationFilter.class)
    .addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
    .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
    .and()
    .logout()
    .addLogoutHandler(keycloakLogoutHandler())
    .logoutUrl("/sso/logout").permitAll()
    .logoutSuccessUrl("/");
}

If the user is already authenticated, the problem is that the Home Page says he is anonymous because the Principal is always null.

But if the user enters the secured page (and Keycloak lets him in because he's already authenticated) when he comes back to the Home, the page contains - correctly - his First Name.

Where is my configuration wrong?

It seems that Spring Security doesn't check the authentication on non secured pages. Is there a way to tell Spring Security to check every page (both secured and non-secured)?

Thanks in advance for your support.

baronKarza
  • 513
  • 6
  • 23

1 Answers1

1

The solution to this problem is to add /** to security context/handling (with permitAll()).

The art is to do it correctly:

So in this case:

 http
  .authorizeRequests()
  .antMatchers("/secure/**").authenticated()
  .antMatchers("/**").pernmitAll()
  .and()...

...should fill the (anonymous) Principal also in "permitted area" (i.e. /**(!) ...and leave secure/** restricted!;).


To the core/title question (once Principal is filled), i think the answer is already given:

..if you use Spring Security (JSP) Taglibs isAnonymous() is handy, and otherwise (in default) you just need to check for hasRole('ROLE_ANONYMOUS') (Ref)

xerx593
  • 12,237
  • 5
  • 33
  • 64
  • Thanks for the valuable suggestions. I implemented the suggested solution and, indeed, the Principal is now populated with `ROLE_ANONYMOUS` and is no longer null. However it is not the solution of the problem since, if an already logged used eners the Home page (public), it is recognized as `anonymous` until he enters a secured page. From then on, he's properly recognized. It seems that Spring Security does not checks the SSO system if `.permitAll()` is present. What else can I try? Thanks a lot for the support. – baronKarza May 28 '21 at 08:37
  • sry, if i don't get it right, but how did he "log in", when he "enters homepage"?? sort of hen-egg problem!? (where i tend to the egg;) ...yes with this solution you can only be anonymous or authenticated....and since you only need to authenticate in secured area (by requirement), every user who "enters" the home page will be anonymous!...until he (visits secured area and) logs in...(and then comes back to home page, welcoming him by his name;) – xerx593 May 28 '21 at 08:47
  • and although, i am xerx593, incarnate....I cannot expect any web site to know this, before i log in... (this would be possible with a "cookie")... – xerx593 May 28 '21 at 08:52
  • 1
    The user is already authenticated because he logged in on another application under the SSO system. So, I'd like that, when he arrives on the home page, Spring Security is able to immediately recognize him with no need to enter a secured page (where everything works as expected). Thx a lot for your time. – baronKarza May 28 '21 at 08:52
  • thanks, now more sense to me! Yes, this sounds like: SSO not correctly configured/Principal won't get filled... ... -> https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor#extracting-principal-and-authorities ;) – xerx593 May 28 '21 at 08:57