SpringBoot - How I can configure samesite none Csrf Cookie (Spring Security 6.2)

346 Views Asked by At

What I have:

  • I have sprint boot api, and angular app in diferents domains (not subdomains), and is not an option change it.
  • I only grant access by cors to my angular domain app.

What I need:

  • I need use Csrf cookie with samesite=none to allow authentication from Chrome browser, beacuse it doesn't work, I think because of default samesite=lax default policy. In firefox is working ok.

What I tried

  • I have updated to spring 2.7 to try use server.servlet.session.cookie.same-site= none property, but it only affect to JSESSIONID cookie. It didn`t work with csrf cookie.
  • I have updated to spring 3 to try use CookieCsrfTokenRepository.setCookieCustomizer() method, I can`t found information about I can use this method to configure the cookie
  • I tried to implement OncePerRequestFilter and modied header Set-cookie, but then, I lost the set-cookie header of JSESSIONID cookie.

¿What i can do to get csrf cookie samesite=none? ¿Is there other solution to run csrf authentication in chrome with diferents domains?

Thanks in advance

1

There are 1 best solutions below

1
On BEST ANSWER

I found the solution

  1. First, create a custom CookieCsrfTokenRepository using setCookieCustomizer metohd with a Consumer<ResponseCookie.ResponseCookieBuilder>
        CookieCsrfTokenRepository tokenRepository = new CookieCsrfTokenRepository();
        tokenRepository.setCookieCustomizer(new Consumer<ResponseCookie.ResponseCookieBuilder>() {
            
            @Override
            public void accept(ResponseCookieBuilder t) {
                t.sameSite("none");
                t.secure(true);
                t.httpOnly(false); //Js can read
            }
        });

  1. Apply at filterChain(HttpSecurity http) method:

@Configuration
@EnableWebSecurity
public class SecurityJavaConfig {
@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        
        //Configuramos el Csrf Token repository para tener una cookie cross domnain
        CookieCsrfTokenRepository tokenRepository = new CookieCsrfTokenRepository();
        tokenRepository.setCookieCustomizer(new Consumer<ResponseCookie.ResponseCookieBuilder>() {
            
            @Override
            public void accept(ResponseCookieBuilder t) {
                t.sameSite(csrfSameSiteCookie);
                t.secure(csrfSecureCookie);
                t.httpOnly(false); //Para que js pueda leer la cookie
            }
        });        
        
        http
            .cors((cors) -> cors.configurationSource(corsConfigurationSource()))
            .csrf((csrf) -> csrf
                    .csrfTokenRepository(tokenRepository)
            )
            .sessionManagement(session  -> session.sessionCreationPolicy(SessionCreationPolicy.ALWAYS))
            //Autorizaciones end-points
            .authorizeHttpRequests((authorize) -> authorize
                    .requestMatchers(HttpMethod.OPTIONS,"/**").permitAll()
                    .requestMatchers(HttpMethod.GET,"/csrf").permitAll()
                    .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());;

 
        return http.build();
    }
}