Jmeter 440错误代码.我该如何解决该错误? [英] Jmeter 440 error code. How can I resolve this error?

查看:83
本文介绍了Jmeter 440错误代码.我该如何解决该错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Genexus制作的Web登录脚本中使用Jmeter和Blazemeter.我遇到的问题在POST中.

每当我尝试进行POST http请求时,Jmeter都会抛出下一件事:

如您所见,在响应正文中,我有一个440 http错误代码.这是登录超时,表示客户端会话已过期,必须再次登录.我曾经有一个403错误代码,但是现在,经过一些安排,我有了440.对于如何解决这个问题,您有任何建议吗?

解决方案

首先,我不是Genexus的专家.我所有的发现都是从黑匣子的角度来看的.

Genexus Security

我发现Genexus至少需要两件事才能在Web应用程序上进行身份验证(我仅测试了Java和.Net生成的应用程序).

  1. GXState 参数.此参数是在发布请求后发送的,据我了解,该参数用作同步器令牌模式",请参见

    已创建变量的名称: GXState

    正则表达式: name ="GXState";value ='(.*?)'

    模板: $ 1 $

    匹配编号: 1

    默认值: NOT_FOUND

  2. GXState 是一个JSON对象,从中我们可以提取 GX_AJAX_KEY 来加密 gxajaxEvt 字符串.请注意,在这种情况下,我发现 GX_AJAX_KEY 是用于加密的密钥,但也可以应用其他一些密钥.我们可以使用Browser Web Console对此进行调试:

  gx.sec.encrypt("gxajaxEvt") 

我们将看到以下内容:" 8722e2ea52fd44f599d35d1534485d8e206d507a46070a816ca7fcdbe812b0ad"

我们发现,所有客户端加密代码都在 gxgral.js 文件中.Genexus使用

要在JMeter脚本中模拟此客户端行为,我们可以使用"JSR 233采样器".获得Rijndael结果的一种方法是使用Bouncy Castle库.我们需要添加此jar

  1. 使用这些变量,我们可以成功发送下一个请求:

我们可以在此处找到该示例JMeter脚本.

.

有关复杂脚本,请参考本指南(需要GXTest)

如果我们在JMeter中收到此异常( java.util.zip.ZipException:不是GZIP格式),请参考此 解决方案

First, I'm not an expert on Genexus. All my findings are from a black-box point of view.

Genexus Security

I found that Genexus requires at least two things to authenticate on Web Application (I tested only Java and .Net generated apps).

  1. The GXState parameter. This param is sent in post request, and from my understanding works as "Synchronizer token pattern", see more info on Cross-site request forgery. We need to send this param on every post request.

  2. The gxajaxEvt parameter. This is very specific to Genexus Apps. In the documentation mentions this parameter is send encrypted in the URL, and this behavior is managed by the "Javascript debug mode property":

# Javascript Debug Mode: Yes
http://{server}:{port}/{webappname}/servlet/com.{kbname}.{objectname}?gxfullajaxEvt,gx-no-cache=1442811265833
# Javascript Debug Mode: No (default value)
http://{server}:{port}/{webappname}/servlet/com.{kbname}.{objectname}?64df96a2d9b8480aed416e470dae529e,gx-no-cache=1442811265833

JMeter Script

  1. So, to get the GXState, we can use the Regular Expression Extractor:

    Name of created variable: GXState

    Regular expression: name="GXState" value='(.*?)'

    Template: $1$

    Match No.: 1

    Default Value: NOT_FOUND

  2. The GXState is a JSON, object, from it we can extract the GX_AJAX_KEY to encrypt gxajaxEvt string. Note that, I found the GX_AJAX_KEY is the key used to encrypt in this case, but some others could apply. We can debug this using Browser Web Console, with this:

gx.sec.encrypt("gxajaxEvt")

We'll see something like this: "8722e2ea52fd44f599d35d1534485d8e206d507a46070a816ca7fcdbe812b0ad"

As we can found, all the client encryption code is in the gxgral.js file. Genexus uses the Rijndael algortihm (Sub set of AES) with block size of 128 bits.

To emulate this client behavior in the JMeter Script we can use the "JSR 233 sampler". A way to get the Rijndael results is use the Bouncy Castle library. We need to add this jar (bouncycastle:bcprov-jdk15to18:1.68) to the JMeter's lib folder to use it.

Our code script will be something like this (Language Groovy 3.0.5/Groovy Scripting Engine 2.0):

import com.jayway.jsonpath.JsonPath
import java.nio.charset.StandardCharsets
import java.util.Arrays
import org.bouncycastle.crypto.BufferedBlockCipher
import org.bouncycastle.crypto.InvalidCipherTextException
import org.bouncycastle.crypto.engines.RijndaelEngine
import org.bouncycastle.crypto.params.KeyParameter
import org.bouncycastle.util.encoders.Hex
import org.apache.jmeter.threads.JMeterContextService
import org.apache.jmeter.threads.JMeterContext
import org.apache.jmeter.threads.JMeterVariables

String gxState = vars.get('GXState')
String gxAjaxKey = JsonPath.read(gxState,'$.GX_AJAX_KEY')
byte[] input = Arrays.copyOf('gxajaxEvt'.getBytes(StandardCharsets.UTF_8), 16)
RijndaelEngine engine = new RijndaelEngine(128)
KeyParameter key = new KeyParameter(Hex.decode(gxAjaxKey))
BufferedBlockCipher cipher = new BufferedBlockCipher(engine)
cipher.init(true, key)
byte[] out = new byte[16]
int length = cipher.processBytes(input, 0, 16, out, 0)
cipher.doFinal(out, length)
String encryptedOutput= Hex.toHexString(out)
log.info 'gx.sec.encrypt("gxajaxEvt")='+encryptedOutput
String gxNoCache = String.valueOf(System.currentTimeMillis())
log.info 'gx-no-cache='+gxNoCache
vars.put('gxajaxEvt', encryptedOutput)
vars.put('gxNoCache', gxNoCache)

The script work like this:

  • First, We get the previos GXState variable extracted.
  • Second, Using JSON Path (Already available in JMeter 5.4) extract the GX_AJAX_KEY property.
  • Third, We apply the Rijndael algorithm over the gxajaxEvt using the GX_AJAX_KEY as a key.
  • We also create the gx-no-cache to handle the cache.

  1. With these variables we can send the next request successfully:

We can found this sample JMeter script available here.

For complex scripts, please refer to this guide (Requires GXTest)

In case we get this exception in JMeter ( java.util.zip.ZipException: Not in GZIP format) please refer this answer too.

这篇关于Jmeter 440错误代码.我该如何解决该错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆