SpringBoot传统WEB应用开启CSRF的流程

 更新时间:2026年01月04日 08:48:03   作者:张占岭  
CSRF是一种Web安全漏洞,攻击者利用受害者合法会话诱使执行非本意操作,文章介绍了CSRF的攻击原理、适用禁用场景以及Spring Security和Django中的禁用示例,同时,对比了不同CSRF保护机制的工作原理和适用场景,感兴趣的朋友跟随小编一起看看吧

CSRF 是什么?

CSRF(Cross-Site Request Forgery,跨站请求伪造) 是一种常见的Web安全漏洞。攻击者利用受害者已经登录的合法会话,诱使受害者执行非本意的操作。

简单比喻:

想象你在咖啡店会员卡里有钱,你每次消费只需要说“用会员卡支付”。攻击者伪装成服务员,在你面前说“用会员卡转账100元到XXX账户”。因为你已经在咖啡店的系统中“登录”了(身份已认证),系统就会执行这个操作。

CSRF攻击原理:

攻击流程:

  • 用户登录:用户登录正常的网站A(如银行网站),获得登录凭证(Cookie/Session)
  • 用户访问恶意网站:用户在同一个浏览器中访问了攻击者的网站B
  • 恶意请求:网站B通过隐藏表单、图片src、AJAX等方式,向网站A发送请求
  • 自动携带凭证:浏览器会自动携带网站A的Cookie
  • 网站A执行请求:网站A看到合法Cookie,误以为是用户的自愿操作

攻击示例:

<!-- 恶意网站上的代码 -->
<img src="https://your-bank.com/transfer?to=hacker&amount=10000" width="0" height="0" />
<!-- 或隐藏表单 -->
<form action="https://your-bank.com/change-email" method="POST">
  <input type="hidden" name="email" value="hacker@evil.com">
</form>
<script>document.forms[0].submit();</script>

为什么有时要禁用CSRF保护?

适用禁用场景:

纯API服务(无浏览器交互)

# 移动App通过API访问后端
# 使用Token认证(JWT/OAuth),而不是Session
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

仅提供非状态改变的操作

GET /api/users          # 只读操作,通常不需要CSRF
POST /api/transfer      # 写操作,需要CSRF

微服务内部通信

# 服务间调用使用服务凭证,而不是用户会话
service-to-service: true

某些特殊框架/场景

// GraphQL通常使用token而不是session
// 或某些实时通信应用

具体框架中的禁用示例:

Spring Security:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()  // 禁用CSRF
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .httpBasic();  // 使用HTTP Basic认证
    }
}

Django:

# settings.py
CSRF_COOKIE_SECURE = False  # 禁用CSRF
# 或针对特定视图
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def api_view(request):
    pass

CSRF保护机制对比:

保护机制工作原理适用场景
CSRF Token服务器生成Token,表单/请求必须携带传统Web应用
SameSite CookieCookie仅在同站请求中发送现代浏览器支持
双重Cookie验证客户端读取Cookie并附加到请求兼容性较好
Referer检查检查请求来源简单但不可靠
无(禁用)不验证纯API、内部服务

何时应该启用/禁用CSRF?

应该启用CSRF的场景:

  • ✅ 传统的基于Session的Web应用
  • ✅ 用户通过浏览器访问的表单提交
  • ✅ 需要用户交互的操作(转账、修改数据)
  • ✅ 使用Cookie/Session进行身份认证

可以禁用CSRF的场景:

  • ✅ 纯REST API,使用JWT/OAuth Token认证
  • ✅ 仅限移动App访问的后端服务
  • ✅ 微服务间的内部通信
  • ✅ 只读的公共API
  • ✅ 使用其他认证方式(API Key、HMAC签名)

禁用CSRF后的替代安全方案:

# 替代方案示例:
1. JWT Token认证:
   每次请求携带: Authorization: Bearer <token>
2. API Key + Secret:
   请求签名: X-Signature: sha256(api_secret + request_data)
3. OAuth 2.0:
   使用Access Token进行授权
4. CORS限制:
   Access-Control-Allow-Origin: https://trusted-domain.com
5. Rate Limiting:
   限制请求频率防止滥用

最佳实践建议:

// 在Spring中,可以针对不同端点配置不同的CSRF策略
public class SecurityConfig {
    protected void configure(HttpSecurity http) {
        http
            // 对Web页面启用CSRF
            .csrf(csrf -> csrf
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
            )
                .requireCsrfProtectionMatcher(
                    new RequestMatcher() {
                        public boolean matches(HttpServletRequest request) {
                            // 仅对特定路径启用CSRF
                            return request.getRequestURI().startsWith("/web/");
                        }
                    })
            .and()
            // API端点使用无状态认证
            .authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS); // API无状态
    }
}

验证 CSRF 是否生效

  • 检查 Cookie:登录后查看浏览器是否有 XSRF-TOKEN Cookie
  • 测试请求
    • 直接发送 POST 请求应该被拒绝(403 错误)
    • 携带正确的 CSRF Token 的请求应该成功
  • 检查响应头:某些配置下,响应头会包含 CSRF Token
# 使用 curl 测试
# 1. 先获取 CSRF Token(从登录后的 Cookie 或响应头)
# 2. 发送带 CSRF Token 的请求
curl -X POST http://localhost:8080/api/test \
  -H "Content-Type: application/json" \
  -H "X-XSRF-TOKEN: YOUR_CSRF_TOKEN" \
  -H "Cookie: XSRF-TOKEN=YOUR_CSRF_TOKEN" \
  -d '{"data": "test"}'

总结:

禁用CSRF的前提条件:

  • 应用不使用Cookie/Session进行身份认证
  • 请求来源可控(如仅限移动App、内部服务)
  • 已实施同等或更强的安全措施替代
  • 确认攻击面不会因此扩大

黄金法则:

如果用户通过浏览器访问你的网站,并且网站使用了Cookie/Session,那么永远不要禁用CSRF保护。只有在完全理解风险并有替代方案时,才考虑为API服务禁用CSRF。

到此这篇关于springboot~传统WEB应用开启CSRF的文章就介绍到这了,更多相关java多线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Spring Boot应用的启动和停止(start启动)

    详解Spring Boot应用的启动和停止(start启动)

    这篇文章主要介绍了详解Spring Boot应用的启动和停止(start启动),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Java AQS中ReentrantLock条件锁的使用

    Java AQS中ReentrantLock条件锁的使用

    ReentrantLock继承了Lock接口, lock方法实际上是调用了Sync的子类NonfairSync(非公平锁)的lock方法。ReentrantLock的真正实现在他的两个内部类NonfairSync和FairSync中,默认实现是非公平锁
    2023-02-02
  • java 静态链表实现示例详解

    java 静态链表实现示例详解

    这篇文章主要为大家介绍了java 静态链表实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • SpringBoot中的自定义starter

    SpringBoot中的自定义starter

    这篇文章主要介绍了SpringBoot中的自定义starter,Starter是Spring Boot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境(条件)进行自动配置,需要的朋友可以参考下
    2024-01-01
  • Java中Map.merge()方法使用示例详解

    Java中Map.merge()方法使用示例详解

    这篇文章主要介绍了Map.merge()方法使用和介绍,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Java反射及性能详细

    Java反射及性能详细

    这篇文章主要介绍了Java反射及性能,现如今的java工程中,反射的使用无处无在。无论是设计模式中的代理模式,还是红透半边天的Spring框架中的IOC,AOP等等,都存在大量反射的影子。下面我们就对该话题进行详细介绍,感兴趣的小伙伴可以参考一下
    2021-10-10
  • java基础的详细了解第二天

    java基础的详细了解第二天

    这篇文章对Java编程语言的基础知识作了一个较为全面的汇总,在这里给大家分享一下。需要的朋友可以参考,希望能给你带来帮助
    2021-08-08
  • Springboot获取bean实例之SpringContextUtil详解

    Springboot获取bean实例之SpringContextUtil详解

    这篇文章主要介绍了Springboot获取bean实例之SpringContextUtil使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • Java实现多对多网络通讯的流程

    Java实现多对多网络通讯的流程

    这篇文章主要介绍了Java实现多对多网络通讯的流程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Java中Thread和Runnable创建线程的方式对比

    Java中Thread和Runnable创建线程的方式对比

    本文主要介绍了Java中Thread和Runnable创建线程的方式对比,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论