【问题标题】:Spring security - 403 status response on OPTIONS callSpring security - OPTIONS 调用上的 403 状态响应
【发布时间】:2020-08-04 17:01:00
【问题描述】:

我在 Heroku 上托管后端,在 Netlify 上托管前端。当我在后端调用端点时,它会发送预检选项,但会给出 403 状态。 我确实搜索了解决方案,但它仍然无法正常工作。

我希望能够使用"POST" 方法调用"/authenticate" 端点,其主体从FE 到BE。

Spring 安全配置(只是配置方法)

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    ...

    @Override
    public void configure(WebSecurity web) throws Exception
    {
        web.ignoring()
                .antMatchers(HttpMethod.POST, "/authenticate", "/register")
                .antMatchers(HttpMethod.GET, "/token")
                .antMatchers("/h2-console/**")
                .antMatchers("/v2/api-docs",
                "/configuration/ui",
                "/swagger-resources/**",
                "/configuration/security",
                "/swagger-ui.html",
                "/webjars/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {

        http
                .cors()
                .and()
                .csrf().disable()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/authenticate").permitAll()
                .antMatchers(HttpMethod.GET, "/user-data").authenticated()
                .anyRequest().authenticated()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(new JwtFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOrigins(List.of(<MY-URL>));
        configuration.setAllowedHeaders(List.of("*"));
        configuration.setMaxAge(Long.valueOf(3600));
        configuration.setAllowedMethods(Arrays.asList("GET","POST", "OPTIONS"));
        configuration.setAllowCredentials(true);

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

        return source;
    }
}

并从 FE 调用

var req = new XMLHttpRequest();
    req.open('POST', API_URL + '/authenticate', true);
    req.setRequestHeader("Content-Type", "application/json");
    req.withCredentials = true;
    req.onreadystatechange = function (aEvt) {
        if (req.readyState === 4) {
            if(req.status === 200) {
                console.log(req.responseText);
                isAuthenticationSucessful = true;
            }
            else
                console.log("Error loading site");
        }
    };

    req.send(JSON.stringify({username, password}));

浏览器开发工具:

Reason: CORS header 'Access-Control-Allow-Origin' missing
Reason: CORS request did not succeed

【问题讨论】:

  • 将安全配置为http.cors().configurationSource(corsConfigurationSource()).and()...
  • @HMD 谢谢!同样在 setAllowedOrigins() 我放了 myurl.com/ ,但是浏览器使用 Origin: myurl.com 发送请求而没有斜杠,这也是需要修复的地方
  • @HMD 我太快了。这并不能解决我所有的问题。它正在发送成功的请求,但浏览器不接受响应。但我让它起作用了,如果你愿意,你可以查看我的答案。再次感谢,您的评论帮助我朝着正确的方向前进。

标签: spring spring-security cors


【解决方案1】:

TL;DR

确保在setAllowedOrigins("https://myrul.com") 中没有斜杠,或者与浏览器发送的来源完全相同。

如果您的端点位于 web.ignoring(... 中,请从此处将其删除并放入(使用我的示例端点)http.authorizeRequests().antMatchers("/authenticate").permitAll()

webhttp 根据我的问题代码)

更长

所以我在评论中说过,使它无法正常工作的一件事是在corsConfigurationSource 中设置setAllowedOrigins("https://myrul.com/")。 请注意尾随斜杠。

但我在开发工具中注意到浏览器发送的原始标头是这样的:Origin: https://myrul.com 没有尾部斜杠。为了使它起作用,我必须将允许的来源更改为正确的来源,如下所示:setAllowedOrigins("https://myrul.com")(不带斜杠)。 这使得浏览器能够向服务器发送请求,并获得 200 响应,但浏览器不接受来自服务器 cuz CORS 的响应。

接下来的事情是我的端点在web.ignoring("/authenticate")... 并且根据这个问题 Spring Security Configuration - HttpSecurity vs WebSecurity 此语句阻止 Spring Security Filter Chain 在它应该标头 Access-Control-Allow-Origin 的位置告诉浏览器它可以接受响应。 MDN Access-Control-Allow-Origin

因此,答案是将我的端点从web.ignoring("/authenticate") 转移到http.authorizeRequests().antMatchers("/authenticate").permitAll()

但这带来了另一个问题,即它现在将进入过滤器链和我的自定义过滤器http.addFilterBefore(new JwtFilter()...,因此请确保根据您的需要采用自定义过滤器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-25
    • 2019-04-15
    • 1970-01-01
    • 2015-10-26
    • 2015-08-16
    • 2015-04-23
    • 2018-06-26
    • 2014-11-14
    相关资源
    最近更新 更多