ServiceNow实例内部REST调用:当前用户身份验证问题求助
问题:ServiceNow内部REST调用以当前用户身份执行失败
我需要在ServiceNow实例中配置内部REST调用,复用现有REST Resource的逻辑,要求调用以当前用户身份执行(比如用户A发起调用时,REST Resource能识别为用户A操作),但无法获取用户明文凭证,必须绕过Authorization头。
尝试过用X-UserToken请求头搭配gs.getSessionToken()的值,但返回401错误;添加JSESSIONID Cookie后,代码陷入无限等待。但通过REST API Explorer执行相同调用却能正常运行。
测试代码
不带Cookie的版本
var request = new sn_ws.RESTMessageV2(); request.setEndpoint('https://dev260217.service-now.com/api/now/table/incident?sysparm_limit=1'); request.setHttpMethod('GET'); request.setRequestHeader("Accept","application/json"); request.setRequestHeader("X-UserToken", gs.getSessionToken() ); // request.setRequestHeader("Cookie", "JSESSIONID=CB997BC0634A850C212C2061F8E4F382"); var response = request.execute(); gs.log(response.getBody());
添加Cookie后的版本
var request = new sn_ws.RESTMessageV2(); request.setEndpoint('https://dev260217.service-now.com/api/now/table/incident?sysparm_limit=1'); request.setHttpMethod('GET'); request.setRequestHeader("Accept","application/json"); request.setRequestHeader("X-UserToken", gs.getSessionToken() ); request.setRequestHeader("Cookie", "JSESSIONID=CB997BC0634A850C212C2061F8E4F382"); var response = request.execute(); gs.log(response.getBody());
错误原因及解决方法
错误原因
X-UserToken仅适用于ServiceNow内部脚本上下文的调用(比如Scripted REST Resource内部的嵌套调用),直接用RESTMessageV2发起外部式请求时,这个头不会被认证模块识别,因此返回401。- 添加
JSESSIONID导致无限等待是因为内部调用触发了会话循环:RESTMessageV2发起的请求会尝试创建新会话,而携带的JSESSIONID指向当前活跃会话,形成死锁。
正确解决方案
方法1:使用gs.invokeRestApi(推荐)
这个方法是ServiceNow专为内部REST调用设计的,会自动继承当前用户的会话和权限,无需手动处理认证:
var params = { sysparm_limit: 1 }; // 格式:gs.invokeRestApi(apiNamespace, apiType, apiPath, method, params) var response = gs.invokeRestApi('now', 'table', 'incident', 'GET', params); gs.log(response.body);
方法2:配置Internal认证Profile并在RESTMessageV2中使用
- 导航到System Web Services > REST > REST Authentication,新建认证配置:
- 类型选择
Internal (Session) - 填写名称(比如
Internal Session Auth)并保存
- 类型选择
- 修改RESTMessageV2代码,使用该认证配置,无需手动添加X-UserToken或Cookie:
var request = new sn_ws.RESTMessageV2(); request.setEndpoint('https://dev260217.service-now.com/api/now/table/incident?sysparm_limit=1'); request.setHttpMethod('GET'); request.setRequestHeader("Accept","application/json"); // 替换为你创建的认证配置名称 request.setAuthenticationProfile('internal', 'Internal Session Auth'); var response = request.execute(); gs.log(response.getBody());
注意事项
确保发起调用的当前用户,对目标REST Resource以及关联的表(比如incident表)有足够的读写权限,内部调用会严格继承当前用户的权限上下文。
内容的提问来源于stack exchange,提问作者Ramón Cordova
相关产品推荐
相关产品推荐

