【问题标题】:Spring Boot Angular 2 and Access-Control-Allow-Origin doesn't work on serverSpring Boot Angular 2 和 Access-Control-Allow-Origin 在服务器上不起作用
【发布时间】:2018-01-01 23:00:53
【问题描述】:

我有一个带有 RestController、自定义安全过滤器和一个 Angular 2 应用程序的 Spring Boot 应用程序,它从 spring 服务请求数据。

由于 Access-Control-Allow-Origin 问题,我有一个设置标题的过滤器。

如果我将 localhost:4200 调用到 localhost:8080,这可以正常工作,但从 localhost:4200 到某些 ip xx.xx.xx.xx:8080 则不起作用。

那么有人有想法吗?

这是我的过滤器:

@Component
public class MyCorsFilter implements Filter {

    public MyCorsFilter() {
        System.out.println("init filter corsssss");
    }

    @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", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}

【问题讨论】:

  • 这似乎只是一个“本地主机”行为,如果我在服务器上部署了 spring boot 应用程序和 angular 应用程序,那么过滤器工作正常并且设置了访问控制标头。跨度>

标签: angular spring-boot


【解决方案1】:

我有同样的问题。

在你的控制器中试试这个:

@Context
private HttpServletResponse servletResponse;

private void allowCrossDomainAccess() {
    if (servletResponse != null) {
        servletResponse.setHeader("Access-Control-Allow-Origin", "*");
    }
}

然后在您的 POST/GET 方法中:

@CrossOrigin
@RequestMapping(value = "/login", method = RequestMethod.POST, consumes = "application/json")
public boolean loginController(@RequestBody User user) throws JSONException, NoSuchAlgorithmException, UnsupportedEncodingException {

    allowCrossDomainAccess();  
    return userService.login(user);
}

最好的问候,

【讨论】:

  • 首先,没有什么不同,在服务器上它不起作用 - 只是在本地主机上,其次它不是一个很好的解决方案,应该有一个通用的标题集
【解决方案2】:

这是一项安全功能。在 Spring 中,您应该控制谁可以访问您的内容,而不是允许任何来源:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().csrfTokenRepository(csrfTokenRepository());
}
    ...
@Bean
public CsrfTokenRepository csrfTokenRepository() { 
    CookieCsrfTokenRepository repository = new CookieCsrfTokenRepository();
    repository.setHeaderName("X-XSRF-TOKEN");
    repository.setCookieHttpOnly(false);
    return repository;
}

然后在 Angular 中更改您的 app.module.ts

import { HttpModule, XSRFStrategy, CookieXSRFStrategy } from '@angular/http';

export function xsrfFactory() { return new CookieXSRFStrategy('XSRF-TOKEN', 'x-xsrf-token'); }
...
  providers: [
     ...
        { provide: XSRFStrategy, useFactory: xsrfFactory },
...

这样,您的 REST 调用将附加 cookie 参数。

或者你也可以这样做——我不建议这样做,但如果你现在不想担心这个可能会有用:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
}

【讨论】:

  • 我不知道是否有完整的 Spring Boot to Angular 示例,即使有,它甚至可能不是您想要的 Spring 版本或您想要的 Angular 版本。我建议按照我上面解释的那样设置安全上下文,然后在 Angular 中,您只需为XSRFStrategy 添加上面的代码。如果您还检查浏览器 REST 调用:检查请求/响应的标头,您应该在那里看到 xcsrf 令牌。请注意,我将 Angular2 应用程序部署到 Tomcat 中,我不记得允许访问控制是否在节点服务器上工作。
猜你喜欢
  • 1970-01-01
  • 2019-03-04
  • 2020-05-27
  • 2017-08-29
  • 1970-01-01
  • 2020-10-18
  • 2023-01-13
  • 2014-06-07
  • 2023-01-23
相关资源
最近更新 更多