Angular 拦截器:headers 添加到请求中的设置不正确,无法从 API 中获取它们

Angular Interceptor: headers added in the request not set properly, can't fetch them from the API

我正在尝试在我的 angular 拦截器中添加一些自定义 headers,如下所示:

@Injectable()
export class HttpJwtAuthInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    localStorage.setItem('token', 'qsdfqsdfqsdfqsdf');
    if (localStorage.getItem('cuid') && localStorage.getItem('token')) {
      request = request.clone({
        setHeaders: {
          'sm_universalid':'blablabla',
          Authorization: `Bearer ${localStorage.getItem('token')}`,
        },
      });
    }



    return next.handle(request);
  }
}

上述拦截器已添加到 app.module.ts:

中的提供程序 属性
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpJwtAuthInterceptor,
      multi: true,
    },
    { provide: BASE_PATH, useValue: environment.apiUrl },
  ],

在我的 spring 启动应用程序中,我添加了一个过滤器来检查是否收到 headers,如果没有收到则抛出异常:

String cuid = request.getHeader(SM_UNIVERSAL_ID);
if (cuid == null || cuid.isEmpty()) {
    log.error("Failed authentication: cuid header not found in the request or it is empty");
    throw new FailedAuthenticationException("cuid header not found in the request or it is empty:"+cuid);
}

不幸的是,过滤器找不到添加的 headers,我尝试记录收到的 headers 列表,我发现它们被添加为 的值access-control-request-headersheader:

如何分别获得那些 header?以及为什么将它们添加到 access-control-request-headers header?

下面是我的 spring 安全性 class 配置的快照(header 过滤器应用在那里):

 @Configuration
@EnableWebSecurity
@Slf4j
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final HeaderVerificationFilter headerVerificationFilter;
    private final JwtAuthorizationFilter jwtAuthorizationFilter;
    private final JwtAuthEntryPoint jwtAuthenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //csrf is disabled because we are not using cookies
        http.csrf().disable();

        // No session will be created or used by spring security
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        //Entry points
        http.formLogin().loginProcessingUrl("/api/login").permitAll()
                //Disallow everything else
                .and().authorizeRequests().anyRequest().authenticated();

        //if a user try to access a resource without having enough permissions
        http.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint);

        // Apply Header and JWT filters
        http.apply(new JwtTokenFilterConfigurer(headerVerificationFilter, jwtAuthorizationFilter, jwtAuthenticationEntryPoint));
    }


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // Allow swagger to be accessed without authentication
        web.ignoring().antMatchers("/v2/api-docs")//
                .antMatchers("/swagger-resources/**")//
                .antMatchers("/swagger-ui.html")//
                .antMatchers("/configuration/**")//
                .antMatchers("/webjars/**")//
                .antMatchers("/public");
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return authenticationManager();
    }
}

我不知道为什么,但我不得不在我的 spring 安全配置 class 中添加我自己的自定义 CORS 策略配置,就像这样:

@Bean
public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // allow requests
    config.setAllowedOriginPatterns(List.of("*"));

    //allowed methods
    config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT", "PATCH"));

    // headers allow in request
    config.setAllowedHeaders(
            Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));

    // headers exposed in response
    config.setExposedHeaders(Arrays.asList("Token", "Authorization", "Content-Type", "Content-Disposition"));
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
}

而且,我必须允许所有类型为 Options 的方法,例如:

@Override
protected void configure(HttpSecurity http) throws Exception {
    //csrf is disabled because we are not using cookies
    http.csrf().disable();

    // No session will be created or used by spring security
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    //Entry points
    http.formLogin().loginProcessingUrl("/api/login").permitAll()
            //Disallow everything else
            .and().authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()//<-- this one
            .anyRequest().authenticated();

    //if a user try to access a resource without having enough permissions
    http.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint);

    // Apply Header and JWT filters
    http.apply(new JwtTokenFilterConfigurer(headerVerificationFilter, jwtAuthorizationFilter, jwtAuthenticationEntryPoint));
}