You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache NiFi ExecuteScript编写JS解密JWT报错求助

NiFi JWE解密脚本报错排查

报错根因

  • 脚本语法不兼容运行环境:NiFi内置的JavaScript执行引擎(Java 8/11自带的Nashorn)不支持ES6规范的async/await、块级const/let声明特性,你在if块内定义async函数、用const声明变量,引擎无法识别对应关键字,直接抛出语法异常。
  • 处理器用法混淆:你提到使用ExecuteCommand处理器,但代码里调用了session、flowFile这类仅在ExecuteScript脚本处理器里才存在的API,ExecuteCommand是用来调用外部系统命令的,本身不提供NiFi流文件操作接口。
  • 代码逻辑错误:定义的decryptJWE函数从未被调用;return语句写在流文件属性写入逻辑前面,后续属性赋值永远不会执行;传入的JWK私钥格式非法,把多个字段拼成了单个字符串;属性写入时传的是固定字符串'jweToken',不是解密后的实际结果。

修复方案

方案1:使用ExecuteScript处理器(直接在NiFi内写JS脚本)

适配Nashorn引擎语法,放弃async/await,改用Promise链式调用处理异步逻辑,注意异步回调内必须完成流文件转移:

// 提前将node-jose的浏览器端打包文件放到NiFi服务器可访问路径,通过load加载
load('/opt/nifi/scripts/node-jose.min.js');
var flowFile = session.get();
if (flowFile != null) {
    var jweToken = flowFile.getAttribute('token');
    // 替换为合法的JWK私钥结构,必须补全kty、d、dp、dq、qi等必填字段
    var privKeyJwks = {
        kty: "RSA",
        p: "aaaaaabbbccccc",
        q: "cddbcbvbvbmm"
    };

    JWK.asKey(privKeyJwks)
        .then(function(privKey) {
            return JWE.createDecrypt(privKey).decrypt(jweToken);
        })
        .then(function(decryptRes) {
            var plainText = decryptRes.plaintext.toString();
            flowFile = session.putAttribute(flowFile, 'decrypted_token', plainText);
            session.transfer(flowFile, REL_SUCCESS);
        })
        .catch(function(err) {
            log.error("JWE解密失败:" + err.getMessage());
            session.transfer(flowFile, REL_FAILURE);
        });
}

方案2:使用ExecuteCommand处理器(调用外部Node.js环境)

写独立的Node.js脚本,不依赖NiFi内置JS API,通过标准输入输出和NiFi交互,兼容性更好:

  1. 先在NiFi服务器上安装Node.js,执行npm install node-jose安装依赖
  2. 新建独立解密脚本/opt/nifi/scripts/decrypt-jwe.js:
const jose = require('node-jose');
let input = '';
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', async () => {
    try {
        // 替换为完整合法的JWK私钥
        const privKeyJwks = {
            kty: "RSA",
            p: "aaaaaabbbccccc",
            q: "cddbcbvbvbmm"
        };
        // ExecuteCommand可配置将token属性注入环境变量传入
        const jweToken = process.env.TOKEN;
        const privKey = await jose.JWK.asKey(privKeyJwks);
        const decryptRes = await jose.JWE.createDecrypt(privKey).decrypt(jweToken);
        // 解密结果输出到标准输出,NiFi会自动捕获为输出流文件内容
        process.stdout.write(decryptRes.plaintext.toString());
    } catch (err) {
        console.error('解密失败:', err);
        process.exit(1);
    }
});
  1. 配置ExecuteCommand处理器:
    • Command Path:填node可执行文件的绝对路径
    • Command Arguments:填上面脚本的绝对路径
    • 配置环境变量传递属性:将流文件的token属性映射为环境变量TOKEN

注意事项

  • 你之前写的{"p:aaaaaabbbccccc,q:cddbcbvbvbmm"}是非法对象,等价于定义了一个键为整串p:aaaaaabbbccccc,q:cddbcbvbvbmm、值为undefined的属性,必须拆分为标准键值对,同时补全JWK规范要求的所有必填字段,否则私钥解析必然失败。
  • 异步操作场景下禁止在Promise回调外执行session.transfer,否则流文件会在解密完成前被提前转移,导致属性丢失、流文件损坏。
  • Java 17及以上版本已经移除Nashorn JS引擎,优先选择ExecuteCommand调用外部Node脚本的方案。

内容的提问来源于stack exchange,提问作者user19296047

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:12:22