在 MeterSphere 中使用預執行指令碼功能生成介面認證簽名

MeterSphere 小助手發表於2020-09-07

前言

目前許多系統的 API 都通過 accessKey + secretKey 生成簽名的方式來完成認證,對於這樣的介面請求,我們可以先使用指令碼生成一個簽名後再將其新增到 MeterSphere 的自定義變數中,但是大部分系統的簽名資訊都與當前時間或請求引數有關,如果每次都需要去執行額外的指令碼進行生成就顯得十分麻煩。接下來我們就以 MeterSphere 自己的 API 介面為例,介紹一下如何在 MeterSphere 中通過預執行指令碼的功能,自動為介面請求生成認證簽名。

MeterSphere API 認證機制

如圖所示,我們可以在 MeterSphere 的 “個人資訊”→“API keys“ 頁面建立 API 認證金鑰。通過 API 呼叫 MeterSphere 介面時需要在請求頭中傳入 accessKey 及 signature 請求頭,其中 accessKey 即為建立 API Key 時生成的 Access Key,signature 通過如下加密演算法得出

加密演算法:AES
加密模式:CBC
填充方式:PKCS5Padding
加密字串:Access Key|當前時間戳 (生成的簽名只在特定的時間範圍內有效,預設30分鐘)
加密金鑰:建立 API Key 時生成的 Secret Key
AES IV:建立 API Key 時生成的 Access Key

操作步驟

在 MeterSphere 建立介面測試,並在場景配置中新增 API 認證需要用到的 accessKey 和 secretKey 作為自定義變數

在該場景中新增一個 HTTP 請求,呼叫 GET/project/listAll 獲取專案列表介面,在該請求的預執行指令碼中,新增以下程式碼生成簽名並將簽名值存入 signature 變數中

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

String accessKey = "${accessKey}";
String secretKey = "${secretKey}";

public static String aesEncrypt(String src, String secretKey, String iv) throws Exception {
byte[] raw = secretKey.getBytes("UTF-8");
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv1 = new IvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv1);
byte[] encrypted = cipher.doFinal(src.getBytes("UTF-8"));
return Base64.encodeBase64String(encrypted);
}

try {
//呼叫加密演算法生成簽名
String signature = aesEncrypt(accessKey + "|" + System.currentTimeMillis(), secretKey, accessKey);
//將簽名值存入 signature 變數中
vars.put("signature",signature);
} catch (Exception e) {
e.printStackTrace();
}

在該請求中新增 accessKey 及 signature 兩個請求頭,accessKey 的值為在場景中配置的 accessKey 變數,signature 的值為上一步通過預執行指令碼計算出來的簽名

在該場景中再次新增一個 HTTP 請求作為對比,同樣呼叫 GET /project/listAll 介面,不新增 accessKey 及 signature 請求頭

儲存並執行該介面測試,在生成的報告中可以看到,新增了認證請求頭的介面呼叫成功,沒有新增認證請求頭的介面呼叫失敗

相關文章