简体   繁体   中英

Why CORS is not working with Spring Security 6?

I tried to apply a CORS configuration using @ch4mp's answer from here: Use Keycloak Spring Adapter with Spring Boot 3

And also followed the guide from here: https://docs.spring.io/spring-security/reference/servlet/integrations/cors.html

Problem is, when I inspect it, I see no CORS headers in my response, as here: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-test-cors.html

I would like to configure CORS globally, any help is appreciated.

@Configuration
@EnableWebSecurity
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SecurityConfig {

    @Value("${eval.required.role.name}")
    private String requiredRoleName;


    @Bean
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http, KeycloakLogoutHandler keycloakLogoutHandler, Jwt2AuthenticationConverter authenticationConverter, ServerProperties serverProperties) throws Exception {

        // If SSL enabled, disable http (https only)
        if (serverProperties.getSsl() != null && serverProperties.getSsl().isEnabled()) {
            http.requiresChannel().anyRequest().requiresSecure();
        } else {
            http.requiresChannel().anyRequest().requiresInsecure();
        }

        CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
        XorCsrfTokenRequestAttributeHandler delegate = new XorCsrfTokenRequestAttributeHandler();
        delegate.setCsrfRequestAttributeName("_csrf");

        CsrfTokenRequestHandler requestHandler = delegate::handle;

        http.cors(withDefaults());

        http.authorizeRequests(auth -> {
            auth.requestMatchers("/**").hasAuthority(requiredRoleName);
            auth.anyRequest().fullyAuthenticated();
        });

        http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(authenticationConverter);

        http.oauth2Login()
                .and()
                .logout()
                .addLogoutHandler(keycloakLogoutHandler)
                .logoutSuccessUrl("/");

        http.csrf(csrf -> csrf
                .csrfTokenRepository(tokenRepository)
                .csrfTokenRequestHandler(requestHandler));

        return http.build();
    }

    @Bean
    public Jwt2AuthoritiesConverter authoritiesConverter() {
        // This is a converter for roles, as embedded in the JWT by a Keycloak server
        return jwt -> {
            final var realmAccess = (Map<String, Object>) jwt.getClaims().getOrDefault("realm_access", Map.of());
            final var realmRoles = (Collection<String>) realmAccess.getOrDefault("roles", List.of());

            return realmRoles.stream().map(SimpleGrantedAuthority::new).toList();
        };
    }

    @Bean
    public Jwt2AuthenticationConverter authenticationConverter(Jwt2AuthoritiesConverter authoritiesConverter) {
        return jwt -> new JwtAuthenticationToken(jwt, authoritiesConverter.convert(jwt));
    }

    public interface Jwt2AuthoritiesConverter extends Converter<Jwt, Collection<? extends GrantedAuthority>> {
    }

    public interface Jwt2AuthenticationConverter extends Converter<Jwt, AbstractAuthenticationToken> {
    }



}


}

And the CORS configuration:

@Component
public class CustomCorsConfiguration {

    @Value("${eval.cors.origin}")//*
    private String corsOrigin;

    @Value("${eval.cors.methods}")//"GET", "POST", "DELETE", "PUT", "OPTIONS"
    private List<String> corsMethods

    @Value("${eval.cors.header}")//*
    private String corsHeaders;

    @Value("${eval.cors.credentials}")//true
    private boolean corsCredentials;

    @Value("${eval.cors.maxAge}")//180
    private Long corsMaxAge;

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList(corsOrigin));
        configuration.setAllowedMethods(corsMethods);
        configuration.setAllowedHeaders(Arrays.asList(corsHeaders));
        configuration.setAllowCredentials(corsCredentials);
        configuration.setMaxAge(corsMaxAge);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);

        return source;
    }

}

在此处输入图像描述

How to check if CORS is working with Spring Boot 3?

Send OPTIONS request to the endpoint of interest and check if required headers are there

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM