Search code examples
spring-securityvaadin7keycloak

Keycloak with vaadin and spring security


I want to secure my vaadin application with keycloak and spring security. I try to use the "keycloak-spring-security-adapter". My problem is that I want also unauthenticated users to use my application, but with less functionality - I do this with method security and checking which roles the current user has in the UI.

Can I configure the filter so that it ignores unauthenticated requests, but If the token is present uses it?

Thanks

Daniel


Solution

  • A working example of what you want can be found in the public-access branch of this github project. It does use Vaadin 8 though.

    In essence, you can setup your application to be partially public, i.e. accessibly to unauthenticated user for certain parts and requires login for others, as follows:

    @Configuration
    @EnableWebSecurity
    @EnableVaadinSharedSecurity
    @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
    public class SecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
    ...
      @Override
      protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().disable();
        http.formLogin().disable();
        http.csrf().disable();
        http
            .authorizeRequests()
            .antMatchers("/vaadinServlet/UIDL/**").permitAll()
            .antMatchers("/vaadinServlet/HEARTBEAT/**").permitAll()
            .anyRequest().permitAll();
        http
            .logout()
            .addLogoutHandler(keycloakLogoutHandler())
            .logoutUrl("/sso/logout").permitAll()
            .logoutSuccessUrl("/");
        http
            .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
            .addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class);
        http
            .exceptionHandling()
            .authenticationEntryPoint(authenticationEntryPoint());
        http
            .sessionManagement()
            .sessionAuthenticationStrategy(sessionAuthenticationStrategy());
      }
    ...
    }
    

    The line http.anyRequest().permitAll(); is the most important where you configure the filter to just allow all requests. You could still update this to only allow public access to certain urls.

    You can then use spring security annotations on methods/views/components to configure your fine-grained access control. E.g:

    @SpringComponent
    @Secured("ROLE_ANONYMOUS")
    public class LoginOperation implements Runnable {
      @Override
      public void run() {
        // login logic
      }
    }
    

    and

    @Secured("ROLE_USER")
    public class LogoutOperation implements Runnable {    
      @Override
      public void run() {
        // logout logic
      }
    }