Gatling 测试 CSRF Spring Security 通过 Web 表单阻止了我的帖子

Posted

技术标签:

【中文标题】Gatling 测试 CSRF Spring Security 通过 Web 表单阻止了我的帖子【英文标题】:Gatling test CSRF Spring Security block my post via a web form 【发布时间】:2018-10-21 19:24:09 【问题描述】:

我想做一个 Gatling 测试并通过带有表单参数的 Post 发送一个表单,但我得到一个 403,因为我的场景是从 spring Security 生成的 CSRF 令牌:

 val sentHeaders = Map(
        "Content-Type" -> "application/x-www-form-urlencoded",
        "User-Agent" -> "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0",
        "Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language" -> "fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3",
        "Connection" -> "keep-alive")
    
  val rechercheAvanceeScn = scenario("RechercheAvanceeAgent").during(TestsPerfConfiguration.dureeTest, "RechercheAvanceeAgentDuration", true)    
      // Phase1: Authentification
      exec(
      http("Authentification")
      .get("/authlogin?sid=1&app=999&code_teleservice=DELTA-T"))
      
      // Phase 2: Form Recherche avancée
      .exec(
      http("RechercheAvanceeForm")
      .get("/recherche/avancee/form")
      .check(status.is(200))
      )
      
      // Phase 3: Recherche Avancée par type de declaration et type de garantie
      .exec(
      http("RechercheAvanceeAgentPost")
      .post("/recherche/avancee/result")
      .headers(sentHeaders)
      .formParam("mrn.comparateur", "EGAL")
      .formParam("mrn.value", "")
      .formParam("typeDeclaration.value", "")
      .formParam("dateDebut.comparateur", "EGAL")
      .formParam("dateDebut.value", "")
      .formParam("dateDebut.valueMax", "")
      .formParam("dateLimitePresentationMarchandises.comparateur", "EGAL")
      .formParam("dateLimitePresentationMarchandises.value", "")
      .formParam("dateLimitePresentationMarchandises.valueMax", "")
      .formParam("modeTransmission.value", "TOUS")
      .formParam("typeProcedureDepart.value", "")
      .formParam("typeProcedureDestination.value", "")
      .formParam("dateFin.comparateur", "EGAL")
      .formParam("dateFin.value", "")
      .formParam("dateFin.valueMax", "")
      .formParam("dateDepotDeclaration.comparateur", "EGAL_HEURE_MINUTES")
      .formParam("dateDepotDeclaration.value", "")
      .formParam("heureDepotDeclaration.value", "00:00")
      .formParam("dateDepotDeclaration.valueMax", "")
      .formParam("heureDepotDeclaration.valueMax", "00:00")
      .formParam("donneesSureteSecurite.value", "")
      .formParam("paysExpedition.value", "")
      .formParam("nomenclatureMarchandises.comparateur", "EGAL")
      .formParam("nomenclatureMarchandises.value", "")
      .formParam("paysDestination.value", "")
      .formParam("valeurFactureTotale.comparateur", "EGAL")
      .formParam("valeurFactureTotale.value", "")
      .formParam("valeurFactureTotale.valueMax", "")
      .formParam("bureauDepart.value", "")
      .formParam("bureauDestination.value", "")
      .formParam("bureauPassage.value", "")
      .formParam("circuitBureauDepart.value", "")
      .formParam("resultatControlesDepart.value", "")
      .formParam("circuitBureauPassage.value", "")
      .formParam("resultatControlesPassage.value", "")
      .formParam("circuitBureauDestination.value", "")
      .formParam("resultatControlesDestination.value", "")
      .formParam("typeGarantie.value", "TYPE_1")
      .formParam("dateDebutGarantie.comparateur", "EGAL")
      .formParam("dateDebutGarantie.value", "")
      .formParam("dateDebutGarantie.valueMax", "")
      .formParam("montantDetteSusceptibleNaitre.comparateur", "EGAL")
      .formParam("montantDetteSusceptibleNaitre.value", "")
      .formParam("montantDetteSusceptibleNaitre.valueMax", "")
      .formParam("grn.comparateur", "EGAL")
      .formParam("grn.value", "")
      .formParam("dateFinGarantie.comparateur", "EGAL")
      .formParam("dateFinGarantie.value", "")
      .formParam("dateFinGarantie.valueMax", "")
      .formParam("_suiteNonLiberationService.booleanValue", "on")
      .formParam("_suiteControleGarantie.booleanValue", "on")
      .formParam("etatDeclaration.value", "VALIDEE_MRN")
      .formParam("result", "")
      .check(status.is(200))
      )
   

错误是: ---- 错误 --------------------------------------------- ----------------------

status.find.is(200),但实际找到了 403 102 (100,0%)

在帖子的参数中,当我执行并从 Firefox 发送表单时,我得到一个令牌 _csrf :"832749f8-7fc2-4fe7-8572-dedd578d1f9f",但我不知道如何获取这个在我的测试中生成的令牌没有 403 错误。

token 存储在参数中,token 实现在带有 JSTL 标记的标头中:.

谁能帮帮我?

【问题讨论】:

【参考方案1】:

您可以使用 check() API 和 saveAs() API 从页面获取值。你应该看看这里:https://gatling.io/docs/current/http/http_check/#saving 您可以通过支票从页面中获取令牌,然后将其保存并稍后使用。

【讨论】:

【参考方案2】:

csrf 令牌将在服务器的响应中发送。正如 CampFire 所说,您只需要找到它的发送位置并使用 check().saveAs() 保存它。

我已经看到 csrf 令牌以 base 64 编码发送,因此您可能需要在服务器响应中注意这一点。

【讨论】:

以上是关于Gatling 测试 CSRF Spring Security 通过 Web 表单阻止了我的帖子的主要内容,如果未能解决你的问题,请参考以下文章

Spring 未在响应时发送 CSRF 令牌

当摘要认证开启时,Gatling 测试失败

性能测试-Gatling

负载,性能测试工具-Gatling

如何使用 gatling 进行 10000 QPS 的负载测试

gatling高性能测试工具