如何为Webflux,Spring-Security,okta-spring-boot-starter和Okta-React正确使用CORS?

问题描述 投票:0回答:1

我的webflux api中有一个CORS webFilter,当我通过邮递员向飞行前检查清单提出“选项”请求时,会收到带有正确标题的响应。但是,当我使用Axios和Okta-React库从浏览器发出相同的请求以检索访问令牌时,将返回401 Unauthorized,并且不返回我要查找的标头。 Axios是否在OPTIONS请求中不包含Bearer Token?我是否需要将选项请求列入白名单以免由OKTA进行身份验证,OKTA不能处理吗?

我正在邮递员SPA中使用相同的访问令牌。我是否在Axios请求中缺少某些内容,是否需要对AORS进行CORS的其他配置?

我很困惑,为什么从邮递员发送时,为一个OPTIONS请求激活webfilter,但在浏览器中从Axios调用时却没有激活?

const getExperience = () => {
        const { accessToken } = authState;

            axios({
                method: "get",
                timeout: 10000,
                headers: {
                    "Authorization": `Bearer ${accessToken}`
                },
                url: `http://localhost:8080/api/v1/professionals`
            }).then( response => {
                setExperience(response.data);
            });
    }
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
            .authorizeExchange()
                .anyExchange().authenticated()
                .and()
            .oauth2ResourceServer()
                .jwt();

        return http.build();
    }

}
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;

import reactor.core.publisher.Mono;

@Component
public class CustomCorsWebFilter implements WebFilter {

    private static final String ALLOWED_HEADERS = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN";
    private static final String ALLOWED_METHODS = "GET, PUT, POST, DELETE, OPTIONS";
    private static final String ALLOWED_ORIGIN = "http://localhost:3000";
    private static final String MAX_AGE = "3600";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {

        if (exchange.getRequest().getMethod() == HttpMethod.OPTIONS) {
            ServerHttpResponse response = exchange.getResponse();
            HttpHeaders headers = response.getHeaders();
            headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
            headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
            headers.add("Access-Control-Max-Age", MAX_AGE);
            headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);

            response.setStatusCode(HttpStatus.OK);
            return Mono.empty();
        }
        return chain.filter(exchange);
    }

}
reactjs axios cors spring-webflux okta
1个回答
0
投票

这是我用WebFlux, React, and Okta设置CORS标头的方法。

@Bean 
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowCredentials(true);
    configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
    configuration.setAllowedMethods(Collections.singletonList("GET"));
    configuration.setAllowedHeaders(Collections.singletonList("*"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

我还使用了如下过滤器:

@Bean
CorsWebFilter corsWebFilter() {
    CorsConfiguration corsConfig = new CorsConfiguration();
    corsConfig.setAllowCredentials(true);
    corsConfig.setAllowedOrigins(List.of("*"));
    corsConfig.setMaxAge(3600L);
    corsConfig.addAllowedMethod("*");
    corsConfig.addAllowedHeader("*");

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

    return new CorsWebFilter(source);
}
© www.soinside.com 2019 - 2024. All rights reserved.