AngularJS SpringBoot no authentication csrf protection



我的系统使用AngularJS 1.6和Spring Boot2.0。我的前端只是一个简单的表单,客户可以用来购买活动门票。当页面加载时,它将获取当前活动事件的详细信息,然后用户可以填写要发布的表单。无需登录/注册,所以它就像谷歌表单一样。我已经将它们构建为单独的项目,因此它们将在不同的端口中运行。现在我想启用 csrf 保护,但我似乎无法使其工作。

我尝试遵循本教程,但没有身份验证部分:https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii。当我这样做时,我在 GET 事件详细信息部分遇到了"缺少 CORS 标头'访问控制-允许来源'",所以我添加了一个 CORS 过滤器:

HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
chain.doFilter(request, response);

添加后,我的 GET 可以工作,但在发布客户的详细信息时遇到相同的 CORS 错误。当我使用邮递员时,我已经可以在 cookie 中看到 XSRF-TOKEN,但不知何故我的后端阻止了传入的 POST。据我了解,angular 会自动使用收到的 XSRF 令牌,因此我在实现 spring 安全性时没有修改前端中的任何内容。

我也试过这个:https://sdqali.in/blog/2016/07/20/csrf-protection-with-spring-security-and-angular-js/。结果完全相同,如果我只是按照教程进行操作,GET 上的 CORS 错误,那么当我添加简单的 CORS 过滤器时,POST 上的 CORS 错误。我的过滤器似乎在运行时混淆了。

我尝试绕过这些教程中的代码以及堆栈中相关问题的一些答案,但所有这些问题都不必处理 CORS 问题。

首先,您应该查看我关于如何使用 spring-boot 和 spring-security 启用 CORS 的评论。

至于CSRF保护,带有弹簧安全性的spring-boot 2直接启用它。然而,要将其与AngularJS一起使用,您需要遵循以下指南: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#csrf-cookie

我们还在开发一个前端 AngularJS 1.6 和后端 spring-boot 2 的项目,但是,由于我们没有在同一 url 上部署前端和后端,因此我们遇到了问题。

例:

  • https://project.company.com/frontend
  • https://project.company.com/backend

服务器生成的cookie是在具有上下文/backend的域https://project.company.com上设置的,这在AngularJS的前端应用程序中是无法读取的。

为了解决这个问题,我们强制我们的服务器发送一个带有上下文/的cookie,以便可以从两个应用程序读取它。

@Configuration
@EnableWebSecurity
public class LdapAuthenticationSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
final CookieCsrfTokenRepository csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
csrfTokenRepository.setCookiePath("/"); // Make sure that the cookie can be read from the backend and the frontend on the same domain.
http.csrf().csrfTokenRepository(csrfTokenRepository);
http.cors();
}
}

如果您的应用程序部署在不同的域上,但具有相同的基础

,如下所示:
  • https://frontend.company.com
  • https://backend.company.com

我建议强制服务器使用类似.company.com的域发送 cookie。但要做到这一点,你需要修改 spring-security 管理 cookie 创建的方式。

最新更新