spring-security 尽管在WebFlux中提供了CORSMap,但未禁用Spring Security Webflux CORS

kiz8lqtg  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(177)

我正在使用Spring Security和WebFlux的http基本身份验证。尽管通过创建一个实现WebFluxConfigurer的类来添加corsMap,禁用cors并添加corsMap,但我仍然无法通过我的Angular应用程序发送任何请求。我添加了两个安全配置文件,代码如下所示:用于配置一般安全性

@Configuration
@EnableReactiveMethodSecurity
@EnableWebFluxSecurity
public class SecurityConfig {
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http){
        return http
                .cors().and().csrf().disable()
                .authorizeExchange()
                .anyExchange()
                .authenticated()
                .and()
                .httpBasic()
                .and()
                .build();
    }
    @Bean
    public ReactiveAuthenticationManager authenticationManager(ReactiveUserDetailsService userDetailsService,
                                                               PasswordEncoder passwordEncoder){
        UserDetailsRepositoryReactiveAuthenticationManager manager = new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService);
        manager.setPasswordEncoder(passwordEncoder);
        return manager;
    }
    @Bean
    public ReactiveAuthenticationManager reactiveAuthenticationManager(ReactiveUserDetailsService userDetailsService,
                                                               PasswordEncoder passwordEncoder) {
        return authentication ->
            userDetailsService.findByUsername(authentication.getPrincipal().toString())
                    .switchIfEmpty(Mono.empty())
                    .flatMap(user -> {
                        final String username = authentication.getPrincipal().toString();
                        final CharSequence rawPassword = authentication.getCredentials().toString();
                        if (passwordEncoder.matches(rawPassword, user.getPassword())) {
                            System.out.println("User has been authentication " + username);
                            return Mono.just(new UsernamePasswordAuthenticationToken(username, user.getPassword(), user.getAuthorities()));
                        }
                        return Mono.just(new UsernamePasswordAuthenticationToken(username, authentication.getAuthorities()));
                    });

    }
        @Bean
    public PasswordEncoder noPasswordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }
}

对于配置CORS:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("localhost:4200")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("Access-Control-Allow-Origin", "Authorization", "Content-Type");
    }
}

错误消息:

Access to XMLHttpRequest at 'http://localhost:8080/course/my-courses' from origin 'http://localhost:4200' 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.
error: ProgressEvent {isTrusted: true, lengthComputable: false, loaded: 0, total: 0, type: 'error', …}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}
message: "Http failure response for http://localhost:8080/course/available: 0 Unknown Error"
name: "HttpErrorResponse"
ok: false
status: 0
statusText: "Unknown Error"
url: "http://localhost:8080/course/available"

我在这里做错了什么?

mccptt67

mccptt671#

由于您使用的是Spring Security,因此应该为Spring Security配置CORS。

@Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http){
        return http
                .cors(cors -> cors
                         .configurationSources(corsConfigurationSource()))
                .csrf().disable()
                .authorizeExchange()
                .anyExchange()
                .authenticated()
                .and()
                .httpBasic()
                .and()
                .build();
    }

    private CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("localhost:4200"));
        configuration.setAllowedMethods(List.of("GET", "POST", "PUT",
                                       "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(List.of("Access-Control-Allow-Origin", 
                                       "Authorization", "Content-Type"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

或者,如果您希望共享SpringMVC的CORS配置,则应该使用默认值配置SpringSecurityCORS

.cors(Customizer.withDefaults())

Spring文档参考:
Reactive Security CORS
Spring安全性和Spring MVC CORS共享

相关问题