2

For our application we had to write a custom OIDCUserService and OIDCUser objects as well as customize Azure's AAD Security Config with Spring.

Here is the code for Spring Boot 2.6 that works.

@EnableWebSecurity
class AADServerConfig {

@Order(1)
@Configuration
static class ApiWebSecurityConfigurationAdapter extends AadResourceServerWebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http)
        http
                .cors()
                .and()
                .csrf().disable()
                .antMatcher("/api/**")
                .authorizeRequests().anyRequest().authenticated()

        http
                .headers()
                .frameOptions()
                .disable()
                .httpStrictTransportSecurity()
                .disable()
    }
}

@Configuration
class HtmlWebSecurityConfigurerAdapter extends AadWebSecurityConfigurerAdapter {
    @Autowired
    private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;
    @Autowired
    private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler;
    @Autowired
    private OAuth2HttpCookieAuthorizationRequestRepository oAuth2HttpCookieAuthorizationRequestRepository;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http)
        http
                .oauth2Login()
                .authorizationEndpoint()
                .authorizationRequestRepository(oAuth2HttpCookieAuthorizationRequestRepository)
                .and()
                .successHandler(oAuth2AuthenticationSuccessHandler)
                .failureHandler(oAuth2AuthenticationFailureHandler)

        http
                .cors()
                .and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/", "/login", "/*.js", "/*.css", "/token", "/actuator/**", "/actuator/prometheus", "/version/**", "/docusign/events/**").permitAll()
                .anyRequest().authenticated()

        http
                .headers()
                .frameOptions()
                .disable()
                .httpStrictTransportSecurity()
                .disable()
    }
}

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration cors = new CorsConfiguration()
    cors.setAllowedOrigins([
            "http://localhost:3000",
            "http://localhost:3001",
            "http://localhost:8080",
            "https://localhost:8080",
            "https://dev-local.panoram.co"
    ])
    cors.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE", "OPTIONS", "FETCH", "PATCH"))
    cors.setAllowCredentials(true)
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource()
    source.registerCorsConfiguration("/**", cors.applyPermitDefaultValues())
    return source
}
}

All fine and good. We now upgrade to Spring Boot 3.x and Azure 5.4 and here is the code like above, but refactored to match the new way to config Spring Security etc. Now CORS is not working. The big difference I see is before we extended AadResourceServerWebSecurityConfigurerAdapter in 2.6 but that no longer exists in Azure 5.4 and we have to use AadResourceServerHttpSecurityConfigurer.

@EnableWebSecurity
class AADServerConfig {

@Order(1)
@Configuration
//com.azure.spring.cloud.autoconfigure.aad.AadResourceServerWebSecurityConfigurerAdapter
class ApiWebSecurityConfigurationAdapter extends AadResourceServerHttpSecurityConfigurer {
    @Override
    void configure(HttpSecurity http) throws Exception {
        super.configure(http)
        http
                .cors(corsCustomizer -> {
                    corsCustomizer.configurationSource(corsConfigurationSource())
                })
                .csrf(csrfConfig -> {
                    csrfConfig.disable()
                })
                .securityMatcher("/api/**")
                .authorizeHttpRequests {}(requestsCustomizer -> {
                    requestsCustomizer.anyRequest().authenticated()
                })

        http
                .headers(header -> {
                    header.frameOptions {frameOptions -> {
                        frameOptions.disable()
                    }}
                    header.httpStrictTransportSecurity {transportConfig ->
                        transportConfig.disable()
                    }
                })
    }
}

@Configuration
class HtmlWebSecurityConfigurerAdapter extends AadWebApplicationHttpSecurityConfigurer {
    @Autowired
    private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;
    @Autowired
    private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler;
    @Autowired
    private OAuth2HttpCookieAuthorizationRequestRepository oAuth2HttpCookieAuthorizationRequestRepository;

    @Override
    void configure(HttpSecurity http) throws Exception {
        super.configure(http)
        http
                .oauth2Login(customizer -> {
                    customizer.authorizationEndpoint {endpointConfig -> {
                        endpointConfig.authorizationRequestRepository(oAuth2HttpCookieAuthorizationRequestRepository)
                    }}
                    customizer.successHandler {oAuth2AuthenticationSuccessHandler}
                    customizer.failureHandler {oAuth2AuthenticationFailureHandler}
                })

        http
                .cors(corsCustomizer -> {
                    corsCustomizer.configurationSource(corsConfigurationSource())
                })
                .csrf(csrfConfig -> {
                    csrfConfig.disable()
                })
                .authorizeHttpRequests(authz ->{
                    authz.requestMatchers("/", "/login", "/*.js", "/*.css", "/token", "/actuator/**", "/actuator/prometheus", "/version/**", "/docusign/events/**").permitAll()
                            .anyRequest().authenticated()
                })

        http.headers(header -> {
            header.frameOptions {frameOptions -> {
                frameOptions.disable()
            }}
            header.httpStrictTransportSecurity {transportConfig ->
                transportConfig.disable()
            }
        })
    }
}

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration()
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000",
            "https://localhost:3000",
            "http://localhost:3001",
            "https://localhost:3001",
            "https://localhost:5001",
            "http://localhost:5001",
            "http://localhost:8080",
            "https://localhost:8080",
            "https://dev-local.panoram.co"))
    configuration.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE", "OPTIONS", "FETCH", "PATCH"))
    configuration.setAllowCredentials(true)
    CorsConfigurationSource source = new UrlBasedCorsConfigurationSource()
    source.registerCorsConfiguration("/**", configuration.applyPermitDefaultValues())
    return source
}
}

I've spent about 2 weeks trying to get CORS to work again, but no luck. What am I doing wrong?

Browser Console Log

1
  • I also just tried and put corsConfigurer.disable() in both places to see if I could disable it an have it work, but it seems to give the same as the screenshot above. Commented Sep 7, 2023 at 18:54

1 Answer 1

2

AadResourceServerHttpSecurityConfigurer doesn't support the configure method, could you try like this:

class ApiWebSecurityConfig {
   @Bean
   SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
       http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
            ...

       return http.build();
   }
}

class HtmlWebSecurityConfig {
    @Bean
    public SecurityFilterChain htmlFilterChain(HttpSecurity http) throws Exception {
        http.apply(AadWebApplicationHttpSecurityConfigurer.aadWebApplication())
            ...

        return http.build();
    }
}

Please refer to https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/spring-security-support?tabs=SpringCloudAzure5x#spring-security-with-azure-active-directory for more info.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.