• 使用Spring Security和Thymeleaf进行CSRF保护


    1. 简介

    Thymeleaf是一个Java模板引擎,用于处理和创建HTML,XML,JavaScript,CSS和纯文本。有关Thymeleaf和Spring的介绍,请查看这篇文章

    在本文中,我们将讨论如何使用Thymeleaf应用程序在Spring MVC中防止跨站点请求伪造(CSRF)攻击。更具体地说,我们将测试HTTP POST方法的CSRF攻击。

    CSRF 是一种攻击,它强制最终用户在当前经过身份验证的 Web 应用程序中执行不需要的操作。

    2. Maven 依赖项

    首先,让我们看看将Thymeleaf与Spring集成所需的配置。在我们的依赖项中需要百里香板弹簧库:

    1. <dependency>
    2. <groupId>org.thymeleaf</groupId>
    3. <artifactId>thymeleaf</artifactId>
    4. <version>3.0.11.RELEASE</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.thymeleaf</groupId>
    8. <artifactId>thymeleaf-spring5</artifactId>
    9. <version>3.0.11.RELEASE</version>
    10. </dependency>
    Copy

    请注意,对于 Spring 4 项目,必须使用thymeleaf-spring4库而不是thymeleaf-spring5。可以在此处找到最新版本的依赖项。

    此外,为了使用 Spring 安全性,我们需要添加以下依赖项:

    1. <dependency>
    2. <groupId>org.springframework.security</groupId>
    3. <artifactId>spring-security-web</artifactId>
    4. <version>5.7.3</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.springframework.security</groupId>
    8. <artifactId>spring-security-config</artifactId>
    9. <version>5.7.3</version>
    10. </dependency>
    Copy

    两个与 Spring 安全性相关的库的最新版本可在此处此处获得。

    3. 爪哇配置

    除了这里介绍的 Thymeleaf 配置之外,我们还需要为 Spring Security 添加配置。为此,我们需要创建类:

    1. @Configuration
    2. @EnableWebSecurity
    3. @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
    4. public class WebMVCSecurity extends WebSecurityConfigurerAdapter {
    5. @Bean
    6. @Override
    7. public AuthenticationManager authenticationManagerBean() throws Exception {
    8. return super.authenticationManagerBean();
    9. }
    10. @Override
    11. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    12. auth.inMemoryAuthentication()
    13. .withUser("user1").password("{noop}user1Pass")
    14. .authorities("ROLE_USER");
    15. }
    16. @Override
    17. public void configure(WebSecurity web) throws Exception {
    18. web.ignoring().antMatchers("/resources/**");
    19. }
    20. @Override
    21. protected void configure(HttpSecurity http) throws Exception {
    22. http
    23. .authorizeRequests()
    24. .anyRequest()
    25. .authenticated()
    26. .and()
    27. .httpBasic();
    28. }
    29. }
    Copy

    有关安全配置的更多详细信息和说明,请参阅Spring 安全系列。

    缺省情况下,CSRF 保护在 Java 配置中启用。为了禁用这个有用的功能,我们需要在configure(...方法:

    .csrf().disable()Copy

    在XML配置中,我们需要手动指定CSRF保护,否则,它将不起作用:

    1. <security:http
    2. auto-config="true"
    3. disable-url-rewriting="true"
    4. use-expressions="true">
    5. <security:csrf />
    6. <!-- Remaining configuration ... -->
    7. </security:http>
    Copy

    另请注意,如果我们使用带有登录表单的登录页面,我们需要始终在登录表单中手动包含 CSRF 令牌作为隐藏参数包含在代码中:

    1. <input
    2. type="hidden"
    3. th:name="${_csrf.parameterName}"
    4. th:value="${_csrf.token}" />
    Copy

    对于其余表单,CSRF 令牌将自动添加到具有隐藏输入的表单中:

    1. <input
    2. type="hidden"
    3. name="_csrf"
    4. value="32e9ae18-76b9-4330-a8b6-08721283d048" />
    Copy

    4. 视图配置

    让我们继续讨论 HTML 文件的主要部分,包括表单操作和测试过程创建。在第一个视图中,我们尝试将新学生添加到列表中:

    1. <!DOCTYPE html>
    2. <html xmlns="http://www.w3.org/1999/xhtml"
    3. xmlns:th="http://www.thymeleaf.org">
    4. <head>
    5. <title>Add Student</title>
    6. </head>
    7. <body>
    8. <h1>Add Student</h1>
    9. <form action="#" th:action="@{/saveStudent}" th:object="${student}"
    10. method="post">
    11. <ul>
    12. <li th:errors="*{id}" />
    13. <li th:errors="*{name}" />
    14. <li th:errors="*{gender}" />
    15. <li th:errors="*{percentage}" />
    16. </ul>
    17. <!-- Remaining part of HTML -->
    18. </form>
    19. </body>
    20. </html>
    Copy

    在此视图中,我们通过提供ID姓名性别百分比(可选,如表单验证中所述)将学生添加到列表中。在执行此表单之前,我们需要提供用户密码,以便在 Web 应用程序中对我们进行身份验证。

    4.1. 浏览器 CSRF 攻击测试

    现在我们进入第二个 HTML 视图。其目的是尝试进行CSRF攻击:

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    5. </head>
    6. <body>
    7. <form action="http://localhost:8080/spring-thymeleaf/saveStudent" method="post">
    8. <input type="hidden" name="payload" value="CSRF attack!"/>
    9. <input type="submit" />
    10. </form>
    11. </body>
    12. </html>
    Copy

    我们知道操作 URLhttp://localhost:8080/spring-thymeleaf/saveStudent。黑客想要访问此页面以执行攻击。

    为了进行测试,请在另一个浏览器中打开HTML文件,而无需登录应用程序。当您尝试提交表格时,我们将收到以下页面:

     

    我们的请求被拒绝,因为我们发送的请求没有 CSRF 令牌。

    请注意,HTTP会话用于存储CSRF令牌。发送请求时,Spring 会将生成的令牌与存储在会话中的令牌进行比较,以确认用户没有被黑客入侵。

    4.2. JUnit CSRF 攻击测试

    如果您不想使用浏览器测试 CSRF 攻击,也可以通过快速集成测试来完成;让我们从该测试的 Spring 配置开始:

    1. @RunWith(SpringJUnit4ClassRunner.class)
    2. @WebAppConfiguration
    3. @ContextConfiguration(classes = {
    4. WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class })
    5. public class CsrfEnabledIntegrationTest {
    6. // configuration
    7. }
    Copy

    并继续进行实际测试:

    1. @Test
    2. public void addStudentWithoutCSRF() throws Exception {
    3. mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON)
    4. .param("id", "1234567").param("name", "Joe").param("gender", "M")
    5. .with(testUser())).andExpect(status().isForbidden());
    6. }
    7. @Test
    8. public void addStudentWithCSRF() throws Exception {
    9. mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON)
    10. .param("id", "1234567").param("name", "Joe").param("gender", "M")
    11. .with(testUser()).with(csrf())).andExpect(status().isOk());
    12. }
    Copy

    由于缺少CSRF令牌,第一个测试将导致禁止状态,而第二个测试将正确执行。

    5. 结论

    在本文中,我们讨论了如何使用Spring Security和Thymeleaf框架防止CSRF攻击。

    本教程的完整实现可以在GitHub 项目中找到。

  • 相关阅读:
    算法与诗数据结构 --- 查找 --- 线性表的查找
    echarts的漏斗图实现
    面试题总结 20231024
    2022年6月编程语言排行,第一名居然是它?!
    基于JAVA的RSA文件加密软件的设计与实现
    CodeSite for .NET实时本地和远程应用程序日志记录
    在Linux中安装宝塔面板
    【每日一题Day342】LC2578最小和分割 | 贪心
    浏览器的工作原理(dns域名服务器,tcp握手,ssl/tls安全协议,关键渲染路径,重绘及回流,防抖和节流)
    大数据到底是好是坏?_光点科技
  • 原文地址:https://blog.csdn.net/allway2/article/details/127706240