0

I am building a Spring Cloud gateway and trying to logout keycloak but it is giving me cors errors, my code it as below:

Security class in which I defined logout code logic:

@Bean
public ServerSecurityContextRepository securityContextRepository() {
    WebSessionServerSecurityContextRepository securityContextRepository =
            new WebSessionServerSecurityContextRepository();

    securityContextRepository.setSpringSecurityContextAttrName("langdope-security-context");

    return securityContextRepository;
}

private LogoutWebFilter logoutWebFilter() {
    LogoutWebFilter logoutWebFilter = new LogoutWebFilter();

    SecurityContextServerLogoutHandler logoutHandler = new SecurityContextServerLogoutHandler();
    logoutHandler.setSecurityContextRepository(securityContextRepository());

    RedirectServerLogoutSuccessHandler logoutSuccessHandler = new RedirectServerLogoutSuccessHandler();
    logoutSuccessHandler.setLogoutSuccessUrl(URI.create("http://localhost:9000/app/Default"));

    logoutWebFilter.setLogoutHandler(logoutHandler());
    logoutWebFilter.setLogoutSuccessHandler(logoutSuccessHandler);
    logoutWebFilter.setRequiresLogoutMatcher(
            ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, "/app/logout")
    );

    return logoutWebFilter;
}

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,ReactiveClientRegistrationRepository repository) {
    // Authenticate through configured OpenID Provider
    http.addFilterAfter(new CustomWebFilter(), SecurityWebFiltersOrder.LAST).authorizeExchange()
            .pathMatchers("/app/logout").permitAll()
            .pathMatchers("/app/authenticate").authenticated()
            .pathMatchers("/app/**").authenticated().and().
            logout().disable()
            .securityContextRepository(securityContextRepository())
            .addFilterAt(logoutWebFilter(), SecurityWebFiltersOrder.LOGOUT)
            .oauth2Login(Customizer.withDefaults());

    // Also logout at the OpenID Connect provider
    http.httpBasic().disable();
    // Require authentication for all requests
   // http.authorizeExchange().anyExchange().authenticated();

    // Allow showing /home within a frame
    http.headers().frameOptions().mode(XFrameOptionsServerHttpHeadersWriter.Mode.SAMEORIGIN);

    // Disable CSRF in the gateway to prevent conflicts with proxied service CSRF
    http.csrf().disable();

    return http.build();
}

Now when from front-end I hit logout it gives me below error:

Access to XMLHttpRequest at 'http://localhost:8280/auth/realms/Default/protocol/openid-connect/auth?response_type=code&client_id=Default&scope=openid%20email%20profile&state=qVQ46iGilTo9o2Ro7CdZzl9kmsMm23jnEqckybucgII%3D&redirect_uri=http://localhost:9000/login/oauth2/code/keycloak&nonce=Z6hMnfYEJaOpuJnX44obCe6GyW8Oc6FSn3MOU_2bRg4' (redirected from 'http://localhost:9000/app/logout') from origin 'http://localhost:9000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

In Keycloak for valid URL I have given * to test but still not working. What am I missing?

dur
  • 15,689
  • 25
  • 79
  • 125
user3458271
  • 638
  • 12
  • 31

1 Answers1

0

I've spent my share of time figuring out keycloak CORS errors and this is what I figured out.

If you have web origins correctly configured (https://stackoverflow.com/a/59072362/20992932) and you are still getting CORS errors there is high probability that the request you are sending is incorrect (jboss handles error before checking client web origin).

To find out if that is the case for you the easiest solution would be to disable same origin policy on the browser (of course for the time of the testing only). Then in network console you should see the actual error response.

Here is how to do it in chrome based browsers:

chromium-browser --disable-web-security --user-data-dir="[some directory here]"

For more see: https://stackoverflow.com/a/59072362/20992932

darz
  • 1
  • 2
  • no it's not correct because when we call spring security default "/logout" it is working fine and same it not working via "/app/logout" so it's nothing related to browser some configuration is missing, have to check how spring secuirty default logout is working when we click on logout button. – user3458271 Jan 17 '23 at 17:54