Sayak Mukhopadhyay
Sayak Mukhopadhyay

Reputation: 1464

Cors issue when redirecting to external auth after logout in Spring Security

I am implementing OIDC based authentication in a Spring Boot based Camunda application. I have been able to successfully implement user logging in but I am facing difficulty in logging the user out. I am using Azure B2C as the auth server and as far as I understand, I need to sign out both from the app and the auth server. Azure gives an endpoint to logout of the form https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Fjwt.ms%2F.

Now, the configuration I use is as such

@Override
protected void configure(HttpSecurity http) throws Exception {
    OidcUserService oidcUserService = new OidcUserService();

    http
        .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
        .and()
        .requestMatchers()
        .antMatchers("/camunda/**", "/api/**", "/login/**", "/oauth2/**")
        .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .oauth2Login()
        .loginPage("/oauth2/authorization/azure-ac")
        .userInfoEndpoint().oidcUserService(oidcUserService)
        .and()
        .and()
        .logout()
        .logoutUrl("/camunda/api/admin/auth/user/default/logout")
        .logoutSuccessUrl("https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Fjwt.ms%2F");
}

Note: I replace the {} with my values.

This doesn't work as I get CORS issues in the browser.

Access to XMLHttpRequest at 'https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Fjwt.ms%2F' (redirected from 'https://localhost:6333/camunda/api/admin/auth/user/default/logout') 
from origin 'https://localhost:6333' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This issue is very similar to Keycloak CORS issue on logout redirect but in my case, the front end is 3rd party and I would prefer not to modify it. Also in the accepted answer it is not clear if frontend must be the one to control the redirection.

Is there anyway to achieve this from Spring itself?

EDIT:

I have been researching and I have found some things that might be useful. Everytime the browser tries to redirect to the external url, it generates a pre-flight request. This request's response has the Access-Control-Allow-Origin: https://localhost:6333 headers but the actual request doesn't have the header. Reading some stuff online it seems like sending a pre flight request to servers that are not expecting one can throw them off. Moreover, the redirect request also contains the X-XSRF-TOKEN header. Is it possible that the presence of the XSRF header is confusing the browser? This the full fetch of the request.

fetch("https://tenant.b2clogin.com/tenant.onmicrosoft.com/policy/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Fjwt.ms%2F", {
  "headers": {
    "accept": "application/json, text/plain, */*",
    "accept-language": "en-US,en;q=0.9",
    "cache-control": "no-cache",
    "pragma": "no-cache",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "cross-site",
    "x-xsrf-token": "THETOKENISHERE"
  },
  "referrer": "https://localhost:6333/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": null,
  "method": "GET",
  "mode": "cors",
  "credentials": "omit"
});

Upvotes: 2

Views: 3422

Answers (1)

MyTwoCents
MyTwoCents

Reputation: 7624

With Spring Security access to Cross-origin sites/URLs are blocked unless you configure it

Sample Example

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://localhost:6333"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

This is just a sample we can fine-tune list and method based on the requirement.

Upvotes: 1

Related Questions