【问题标题】:Spring Boot CORS 403 No 'Access-Control-Allow-Origin' header is present on the requested resourceSpring Boot CORS 403 请求的资源上不存在“Access-Control-Allow-Origin”标头
【发布时间】:2017-10-08 00:36:06
【问题描述】:

我正在学习使用 Spring Boot 1.5.2 作为服务器和 angularJS 1.6 作为客户端来开发一个 RESTful 应用程序。当我尝试使用“localhost:8080/login”从“localhost:9000/login”登录时,我不断收到 403 响应。

XMLHttpRequest 无法加载 http://localhost:8080/login。不 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://127.0.0.1:9000” 使用权。响应的 HTTP 状态代码为 403。

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

~

import org.apache.catalina.filters.*;
import org.apache.catalina.filters.CorsFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.sql.DataSource;

@Order(1)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Qualifier("dataSource")
    @Autowired
    private DataSource dataSource;

    protected void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic().and()
                .authorizeRequests()
                .antMatchers("/", "/home", "/login", "logout", "/customers").permitAll()
                .anyRequest().authenticated().and()
                .csrf()
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .and()
                .cors()
                    .disable();
    }


    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setSessionAttributeName("_csrf");
        return repository;
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }
}

~

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
class SimpleCORSFilter implements javax.servlet.Filter {

    private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

    public SimpleCORSFilter() {
        log.info("SimpleCORSFilter init");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, HEAD, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, z-requested-with, X-Requested-With, Authorization, Content-Type, Access-Control-Allow-Origin");

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

}

如何正确设置 Spring Boot 安全性以使其能够在没有 CORS 和 CSRF 问题的情况下与 angularJS 一起使用?

【问题讨论】:

  • 你解决了吗?

标签: spring security spring-boot cors


【解决方案1】:
@CrossOrigin(origins = "**", maxAge = 3600)

可以解决问题,但我认为这不是一个非常强大的解决方案。到目前为止,我发现我的一些端点可以使用它,而一些端点仍在提供 CORS 错误。 尽管如此,仍然是一个快速破解,对于更大的项目,我认为设置 CORSFilters 是要走的路,我相信这就是你试图做的。

【讨论】:

    【解决方案2】:

    您需要在网络安全过滤器之前以正确的顺序添加过滤器,如下所示:

    .addFilterBefore(
        new LoginFilter(new SimpleCORSFilter()),
        UsernamePasswordAuthenticationFilter.class
    )
    

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 2014-07-06
      • 2017-04-11
      • 2022-07-28
      • 1970-01-01
      • 2020-02-13
      • 2019-08-12
      • 2018-03-05
      • 2019-10-10
      相关资源
      最近更新 更多