属性函数

您可以使用配置 API 样本和语法来编写定制函数。

概述

使用函数在以单点登录认证令牌格式将属性值传递给应用程序前或者在供应帐户时引用、变换和组合属性值。 IBM® Verify函数可以访问用于向 进行身份验证的身份源凭据、存储在 Cloud Directory 中的用户对象(SCIM 格式)以及任何外部 API 端点。 例如,可将名为 formalDisplayName 的属性创建为固定值属性,并且可指定以指定方式并置 user.name.givenNameuser.name.familyName 的函数。
注: 该函数的语法类似于C语言和 JavaScript™。 不过,它基于一种单行表达式语言—— Google 通用表达式语言扩展。

要配置高级规则属性,请在管理控制台中转到 “目录 ”> “属性”。 然后在应用程序配置中映射这些属性,方法与其他所有属性类型的映射类似。

有关在高级工作流中使用功能代码的更多信息和示例,请参阅《 编排指南》。

领域对象

术语“域对象”是一个笼统短语,用于指示可在属性的定制函数中访问的所有可能的对象。

Cloud Directory 用户

每当有用户通过身份验证 Verify 时,Cloud Directory 中就会创建一个用户账户。 此帐户表示为 SCIM 对象。 在以下示例中,使用了以下 Cloud Directory 用户帐户。

以下 SCIM 对象是用户帐户。
{
  "id": "600000A3DD",
  "userName": "google-oauth2|1033116550041553242@jke.samlfed.com",
  "emails": [
    {
      "type": "work",
      "value": "jessica@jke.com"
    }
  ],
  "meta": {
    "created": "2019-04-26T09:21:35Z",
    "location": "https://jke.cloudidentity.com/v2.0/Users/600000A3DD",
    "lastModified": "2019-04-26T09:21:35Z",
    "resourceType": "User"
  },
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
    "urn:ietf:params:scim:schemas:extension:ibm:2.0:User"
  ],
  "name": {
    "formatted": "Jessica Hill",
    "familyName": "Hill",
    "givenName": "Jessica"
  },
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "manager": {
      "value": "6030101TP6"
    }
  },
  "urn:ietf:params:scim:schemas:extension:ibm:2.0:User": {
    "userCategory": "federated",
    "twoFactorAuthentication": false,
    "realm": "jke.samlfed.com",
    "unqualifiedUserName": "google-oauth2|1033116550041553242",
    "customAttributes": [
        { 
          "name": "car",
          "values": [ "Ford Mustang Mach-E", "Maruti Suzuki 800" ]
        },
        {
          "name": "hobbies",
          "values": [ "Reading", "Running", "Gaming", "Star Wars" ]
        }
    ]
  },
  "active": true
}
注: 在 SCIM 对象中,定义了两个自定义属性—— carhobbies。 这些属性是可通过管理控制台配置的模式扩展。 Verify 可以通过 Users API 向用户对象添加属性。
语法 描述 示例
user.$property 访问 $property。 可以同时使用 .[".."]
user.name.familyName + ", " + user.name["givenName"]

结果:

Hill, Jessica
user.$values.filter(x, $condition) $values:列表。 filter 函数根据 $condition 抽取值。
user.emails.filter(x, x.type == "work")[0].value

结果:

jessica@jke.com
user.getCustomValues($attrName) 用于将自定义属性值作为列表返回的函数。 $attrName: 如果用户对象中不存在该属性,则该属性的名称将返回 null。
user.getCustomValues("car")

结果:

["Ford Mustang Mach-E","Maruti Suzuki 800"]
user.getCustomValue($attrName) 获取列表中第一个自定义属性值的功能。 $attrName: 用户对象中属性的名称。如果该属性不存在,则返回空字符串 ("")。
user.getCustomValue("hobbies")

结果:

Reading
user.getManager() 获取当前用户经理信息的函数。 此函数返回经理的用户帐户(作为 SCIM 对象)。 如果未针对用户指定经理,那么返回一个空的 JSON 对象。 如果返回了一个管理器对象,则可以像使用用户对象一样使用它,也就是说,可以对该对象调用各种函数。
user.getManager().name.formatted

结果:

Jacob Jones
user.getRoles() 获取当前用户权限的函数。 该函数将用户的权限列表作为 JSON 对象返回。 如果返回了权限列表,则可以将其作为 JSON 对象使用。
user.getRoles().resources[0].name

结果:

Basic access
user.getFIDO2Registrations($search) 用于获取当前用户 FIDO2 注册信息的函数。 该函数返回属于该用户的 FIDO2 注册列表。 可选择提供搜索参数 $search 。 支持的搜索参数可在此处查看: https://docs.verify.ibm.com/verify/reference/getfidoregistrations_v20
user.getFIDO2Registrations("enabled=true").fido2[0].enabled

结果:

true
user.getFIDO2RegistrationByID($id) $id获取当前用户(ID 为.)的 FIDO2 注册信息的函数。
user.getFIDO2RegistrationByID("e8bf1dac-8245-452b-b7c4-8a700a1eb078").fido2[0].id

结果:

e8bf1dac-8245-452b-b7c4-8a700a1eb078
user.getDynamicGroups() 获取当前用户动态组的功能。 该函数将用户的动态群组列表作为 JSON 对象返回。
user.getDynamicGroups().resources[0].name

结果

Security department manager

用户管理功能

如果需要对 Cloud Directory 中的用户执行读取、创建和更新操作,CELx 提供了以下功能。

这些函数的返回值是一个如下定义的映射对象。 这使得在 CELx 函数中进行错误处理时具有灵活性。 对于 error ,空字符串表示操作成功。
{
"result": <result of the operation>,
"error": <error message, in case of failures>
}
语法 描述 示例
findUsers($filter) 该函数返回符合指定筛选条件的用户列表。

$filter: 用于定义匹配条件的字符串,其格式应符合 GET Users API 的规定。 搜索结果最多显示10个用户。

如果未找到匹配的用户,则返回一个空列表。

findUsers('emails ew "@jke.com"')
findUsers($filter, $attributes) 该函数返回符合指定筛选条件的用户列表。 每个匹配的用户都会返回参数 $attributes 中指定的属性。

$filter: 定义匹配条件的字符串。

$attributes: 结果中应返回的 scimNames 字符串数组。

请参考 GET Users API 中定义的查询参数格式。 搜索结果最多显示10个用户。

如果未找到匹配的用户,则返回一个空列表。

findUsers('emails ew "@jke.com"', ["emails", "name.givenName"])
findUsers($filter, $attributes, $count) 该函数返回符合给定筛选条件且数量不超过 $count 的用户列表。 每个匹配的用户仅返回在 参数中 $attributes 指定的属性。

$filter: 定义匹配条件的字符串。

$attributes: 一个包含 scimNames 的字符串数组,该数组应作为结果返回。

$count: 用于指定要返回的用户最大数量的整数,上限为 10。 大于 10 的任何值都将被忽略,并设置为 10。 请参考 GET Users API 中定义的查询参数格式。

如果未找到匹配的用户,则返回一个空列表。

findUsers('emails ew "@jke.com"', ["emails", "name.givenName"], 3)
findUser($filter) 该函数返回一个符合给定过滤条件的用户。

$filter: 该字符串定义了匹配条件,其格式遵循 GET Users API 的规定。

如果匹配到多个用户,或者未匹配到任何用户,则会返回错误。

findUser('emails eq "jessica@jke.com"')
findUser($filter, $attributes) 该函数返回一个符合给定过滤条件的用户。 该函数仅返回参数 $attributes 中指定的属性。

$filter: 定义匹配条件的字符串。

$attributes: 包含 scimNames 的字符串数组,该数组应作为结果返回。 请参考 GET Users API 中定义的查询参数格式。

如果匹配到多个用户,或者未匹配到任何用户,则会返回错误。

findUser('emails eq "jessica@jke.com"', ["emails", "name.givenName"])
getUser($uid) $uid该函数返回与给定对象关联的用户。 如果用户不存在,则返回错误。
getUser("504K8664N6")
createUser($m) 该函数会根据给定的属性值创建一个用户。

$m:一张映射表,其中包含属性ID/名称及其对应的用户期望值。

这些属性 ID 可在 GET Attributes API 的响应中找到。 ID 和属性名称可以互换使用。

emailusername 属性的值是必填的。 其余参数均为可选。

要指定新用户的密码,请在 $m 中添加一个名称为 password 的属性,并将明文密码作为其值。

result成功后,将返回创建的用户 SCIM 对象。

createUser({'3':'jessica@jke.com', 'userName':'Jessica', '3f31edcf-19e8-46a4-b87e-e50c25dc1358':'Manager', 'hobbies':['Reading', 'Swimming'], '6': 'Jessica', '7': 'Doe'})
createUser($m, $opts) 该函数会根据给定的属性值和附加选项创建一个用户。

$m:一张映射表,其中包含属性ID/名称及其对应的用户期望值。

$opts: 创建用户时可指定的其他选项列表。

这些属性 ID 可在 GET Attributes API 的响应中找到。 ID 和属性名称可以互换使用。

emailusername 属性的值是必填的。 其余参数均为可选。 要指定新用户的密码,请在 $m 中添加一个名为 password 的属性,并将明文密码作为其值。

$opts 目前允许使用以下属性:

  • notifyType :该属性指定要发送给用户的通知类型。 默认值是 EMAIL.
  • notifyPassword :布尔值,用于指示发送给用户的通知中是否包含用户的密码。 默认值是 true. 如果 notifyType 设置为 NONE,则此属性不适用。
  • notifyManager :布尔值,用于指示在用户设置或修改密码时,是否应将通知发送给用户的经理(如果已设置)。 默认值为 false. 如果 notifyType 设置为 NONE,则此属性不适用。
  • acceptInitialPassword :如果设置为 true,则用户首次登录时无需更改密码。

result成功后,将返回创建的用户 SCIM 对象。

createUser({'3':'jessica@jke.com', 'userName':'Jessica', '3f31edcf-19e8-46a4-b87e-e50c25dc1358':'Manager', 'hobbies':['Reading', 'Swimming'], '6': 'Jessica', '7': 'Doe'}, {'notifyType':'NONE', 'acceptInitialPassword': 'true'})
updateUser($uid, $m)

该函数会将给定的用户更新为指定的属性值。

$uid: 待更新的用户 ID。

$m:一张映射表,其中包含属性ID/名称及其对应的用户期望值。

这些属性 ID 可在 GET Attributes API 的响应中找到。 ID 和属性名称可以互换使用。

更新成功时,会返回 success 字符串作为结果。 不会返回该用户对象。

updateUser('6050007SGF', {'3':'jessica@redbank.com', '3f31edcf-19e8-46a4-b87e-e50c25dc1358':'President', 'mobile_number': '502513585', 'work_country': 'Singapore'})
身份源凭证
Verify当用户登录时,身份源凭据属性会被添加到登录会话中,并可在自定义函数中进行访问。 请考虑用户使用 SAML 联合身份提供者进行登录,SAML 断言包含名为 userRoles 的属性语句,并且该属性语句设置为 marketinghelpdesk
idsuser 属性可作为具有字符串键和字符串数组值的映射提供。 例如,
{
  "userRoles": ["marketing", "helpdesk"],
  "displayName": ["Jessica J. Hill"],
  "phone": ["+12324321234"],
  "employeeId": "eid1234"
}
语法 描述 示例
idsuser.$property 访问 $propertyidsuser 中的值始终是字符串的数组。
idsuser.userRoles[1]

结果:

helpdesk
idsuser.getValue($property) 以字符串形式返回 $property 的值。 如果值数组具有多个条目,将返回第一个项目。 如果 $property 不存在,那么将返回一个空字符串。
idsuser.getValue('userRoles') 

结果:

"Marketing"
idsuser.getValues($property) 以字符串数组形式返回 $property 的所有值。 如果 $property 不存在,那么将返回 nil 对象。
idsuser.getValues('userRoles') 

结果:

["Marketing", "helpdesk]"
HTTP 请求上下文

IBM Verify当用户登录时,可以在自定义函数中访问传入的 HTTP 请求上下文。 如果用户使用 OAuth 流进行登录,并且客户机发送 client-ipuser-agent 信息,那么 requestContext 可以抽取该信息。 它可用于向外调用外部端点以确定用户的风险分数。

requestContext 以包含字符串键和字符串数组值的映射形式提供。 例如,
{
  "User-Agent": ["Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405"],
  "devicePlatform": ["MACOS"],
  "x-forwarded-for": ["116.15.12.181"]
}
表 1. HTTP 请求上下文
语法 描述 示例
requestContext.$property 访问 $propertyrequestContext 中的值始终是字符串的数组。
requestContext.devicePlatform[1]

结果:

MACOS
requestContext.getValue($property) 以字符串形式返回 $property 的值。 如果值数组具有多个条目,将返回第一个项目。 如果 $property 不存在,那么将返回一个空字符串。
requestContext.getValue('x-forwarded-for')

结果:

116.15.12.181
requestContext.getValues($property) 以字符串数组形式返回 $property 的所有值。 如果 $property 不存在,那么将返回 nil 对象。
requestContext.getValues('x-forwarded-for')

结果:

["116.15.12.181"]
属性上下文
上下文对象包含编写函数时可使用的属性的特定特性的键值对。 这些特性的值仅在此属性查找的上下文中有效。 可以使用 ctx 键来访问此对象。
以下特性可用于上下文对象:
语法 描述 示例
ctx.currentValue 访问运行此函数前评估的属性值。 在属性配置中指定此值的数据类型。 如果无法将值强制转换为此数据类型,那么此值将设置为 null。
ctx.currentValue.toUpper

标准运算符

属性函数中支持的运算符包括在任何编程语言中提供的标准列表。 例如,+-*/><。可使用 + 来连接字符串。
运算符 描述 示例
== 等于比较
user.name.givenName == "Jessica"
!= 不等于比较
idsuser.myroles[0] == "marketing"
|| 逻辑 OR 比较
user.name.givenName == "Jessica" || user.name.formatted.startsWith("Hill")
&& 逻辑 AND 比较
1 == 1 && 2 == 2
[ ] 映射访问
user["name"]["givenName"]
+ 并置和添加,具体取决于类型
"Hello" + " " + "World"
- 减法
10 - 5
* 乘法
5 * 2
/ 部门
20 / 4
> 大于条件
1 > 2
< 小于条件
1 < 2
>= 大于或等于
1 >= 1
<= 小于或等于
1 <= 1
? 三元 if 运算符
a == b ? true : false

标准函数

属性函数可以使用标准函数来执行任务,例如,处理属性值和访问列表中的元素。
表 2. 字符串函数
语法 描述 示例
$string.contains($fragment) 检查 $string 中是否包含 $fragment。
"helloworld".contains("hello")

结果:

true
$string.endsWith($fragment) 检查 $string 是否以 $fragment 结尾。
"hello world".endsWith("old")

结果:

false
$string.matches($regex) 检查 $regex 是否与 $string 中的模式匹配。
"foo".matches("k.*")

结果:

false
$string.toUpper() $string 转换为大写。
"hello".toUpper()

结果:

HELLO
$string.toLower() 将 $string 转换为小写。
"HEllO".toLower()

结果:

hello
$string.base64Encode() Base64 编码 $string
"hello".base64Encode()

结果:

aGVsbG8=
$string.base64Decode() Base64 解码 $string
"aGVsbG8=".base64Decode()

结果:

hello
$string.base64URLEncode() Base64URL 对 $string 进行编码。
"hello_world!".base64URLEncode()

结果:

aGVsbG9fd29ybGQh

$string.base64URLDecode() Base64URL 解码 $string。
"aGVsbG9fd29ybGQh".base64URLDecode()

结果:

hello_world!

$string.size() $string 的大小
"hello".size()

结果:

5
$string.substring($begin,$end) 返回 $begin index (including)$end index (excluding) 之间的字符串。
"hello".substring(1,4)

结果:

ell
$string.split($delim) 返回由 $delim 拆分的字符串的数组。
"hello".split("e")

结果:

["h","llo"]
$string.replaceAll($old,$new) 将出现的所有 $old 替换为 $new
"hello".replaceAll("l","p")

结果:

heppo
$string.matchAndReplaceAll($regex, $newStr) $regex 的所有匹配项替换为 $newStr
"some12#$text".matchAndReplaceAll("[^a-zA-Z]+", "-")

结果:

some-text
$string.indexOf($str) $str返回. 的首次出现位置。
"hello".indexOf("l")

结果:

2
$string.lastIndexOf($str) $str返回. 的最后一次出现位置。
"hello".lastIndexOf("l")

结果:

3
表 3. 列表函数
语法 描述 示例
$values.size() 列表 $values 的大小
["hello", "world"].size()

结果:

2

$values.filter(x, $condition) $condition 过滤 $values
["hello", "world", "helios"].filter(x,
            x.startsWith("hel"))

结果:

["hello", "helios"]

$values.all(x, $condition) 检查是否所有 $values 都满足 $condition
["hello", "world", "helios"].all(x,
            x.contains("hel"))

结果:

false

$values.exists(x, $condition) 检查是否有任何值满足 $condition
["hello", "world", "helios"].exists(x,
            x.contains("hel"))

结果:

true

$values.exists_one(x, $condition) 检查是否正好有一个值满足 $condition
["hello", "world", "helios"].exists(x,
            x.contains("hel"))

结果:

false

$values.map(x, $op) 对每个值运行 $op
["hello", "world", "helios"].map(x, x.toUpper())

结果:

["HELLO","WORLD","HELIOS"]

stringToJson($s) 将字符串 $s 转换为 JSON 数组。
stringToJson('[{\"hello\":\"world\"},{\"key\":\"value\"}]')

结果:

[{"hello":"world"},{"key":"value"}]

jsonToString($json) 将列表 $json 转换为字符串。
jsonToString(["hello","world","helios"])

结果:

"[\"hello\",\"world\",\"helios\"]

joinStrings($values, $s) 将列表 $values 中的字符串连接至分隔符 $s。
joinStrings(['hello','world','helios'], ' + ')

结果:

"hello + world + helios"

$values.flatten() 将列表列表 $values 转换为单个列表。
[[1,2],["a","b","c"]].flatten()

结果:

[1,2,"a","b","c"]

注意: 您也可以对 Map 对象调用 List 函数。 该函数针对 Map 中的键列表运行。 例如,如果输入包含:
{
idsuser: {
"attr1":"value1",
"attr2":"value2"
}
}
那么对于函数 idsuser.exists(x, $condition),x 为 [ "attr1", "attr2" ]
表4。 哈希函数
语法 描述 示例
sha256($value) 计算指定字符串的 sha256 散列值。 输出结果是十六进制值的字符串表示形式。
sha256('hello')

结果:

`2cf24dba...`

sha512($value) 计算指定字符串的 sha512 散列值。 输出结果是十六进制值的字符串表示形式。
sha512('hello')

结果:

`9b71d224...`

hmacSha1($value, $key) 计算给定字符串的 HMAC-SHA1 值(键为 $key)。 输出结果是十六进制值的字符串表示形式。
hmacSha1('hello','key')

结果:b34ceac4516ff23a143e61d79d0fa7a4fbe5f266

表5。 Hex/Base64 功能
语法 描述 示例
base64ToHex($value) 将字符串 $value 转换为十六进制数,该字符串采用 base64-encoded 格式。
base64ToHex('Gis8Tw==')

结果:

1a2b3c4f

hexToBase64($value) 将十六进制值 $value 转换为 base64-encoded 字符串。
hexToBase64('1a2b3c4f')

结果:

Gis8Tw==

base64URLEncodedToHex($value) 将字符串 $value 转换为十六进制数( base64URL-encoded )。
base64URLEncodedToHex('Gis8TV5v')

结果:

1a2b3c4d5e6f

hexToBase64URLEncoded($value) 将十六进制值 $value 转换为 base64URL-encoded 字符串。
hexToBase64URLEncoded('1a2b3c4d5e6f')

结果:

Gis8TV5v

表6。 映射函数与对象函数
语法 描述 示例
has($m.$p) 检查映射 $m 是否包含属性 $p。
has({ "hello": "world" }.hello)

结果:

true

has($m, $p) 用于检查映射 $m 是否包含属性 $p。 对于包含特殊字符(例如点)的属性名称,这种做法非常方便。
has({ "email.address": "abc@email.com"}, "email.address")

结果:

true

jsonToString($m) 将地图 $m 转换为字符串
jsonToString({"hello":"world"})

结果:

"{\"hello\":\"world\"}"

stringToJson($s) 将字符串 $s 转换为映射。
stringToJson("{\"hello\":\"world\"}")

结果:

{"hello": "world"}

jsonToFormURLEncoded($m, $doUrlEncode) 将映射 $m 转换为表单。 如果 $doUrlEncode 设置为 true,则表单将采用 URL 编码。
jsonToFormURLEncoded({'hello':'world', 'key1':'value 1'}, true)

结果:

"hello=world&key1=value+1"

$m.put($k, $v) 将键 $k (类型为字符串)及其值 $v (类型为对象)插入到映射 $m 中。 $v$k如果该映射 $m 中先前已存在该键的值,则旧值将被新值替换。
{"hello": "world"}.put("key1",
    "value1")

结果:

"{"hello": "world", "key1": "value1"}
$m.putAll($v) $m将地图 $v 的内容插入到 地图 中。 $v$v如果该映射 $m 中先前已存在该键对应的值,则该映射 $m 中的旧值将被该映射中的新值替换。
{"hello": "world"}.putAll({"key1": "value1", "test":
      true})

结果:

"{"hello": "world", "key1": "value1", "test": true}
$m.remove($k) 如果存在,则从映射 中移除类型为字符串的键 $k 的映射 $m 项。
{"hello": "world", "key1":
    "value1"}.remove("key1")

结果:

{"hello": "world"}
$m.removeAll($l) $l 如果存在,则从映射 $m 中移除该键列表的所有映射。
{"hello": "world", "key1": "value1", "test":
      true}.removeAll(["key1", "test"])

结果:

{"hello": "world"}
注意: 若要检查名称中是否包含保留字符的属性,请 exists 使用 List 函数。
idsuser.exists(x, x == "ext:idsource_attr1")
如果该属性存在,那么将返回 true,否则将返回 false
表7。 时间戳函数
语法 描述 示例
now 返回当前时间的时间戳记对象。
now

结果:

"2021-08-17T08:24:58Z"
timestamp($s) 根据 RFC3339 将输入字符串$s进行转换,并返回一个时间戳对象。
timestamp(1629188698)

结果:

"2021-08-17T08:24:58Z"

$t.getDate() 以基于 1 的索引方式返回时间戳记 $t 中的当月日期(整数)。
timestamp('2021-08-17T08:24:58Z').getDate()

结果:

17
$t.getDayOfMonth() 以基于零的索引形式返回时间戳记 $t 中的当月日期(整数)。
timestamp('2021-08-17T08:24:58Z').getDayOfMonth()

结果:

16
$t.getDayOfWeek() 以基于零的形式返回时间戳记 $t 中的当周日期(整数,零表示星期日)。
timestamp('2021-08-17T08:24:58Z').getDayOfWeek()

结果:

2
$t.getDayOfYear() 以基于零的索引形式返回时间戳记 $t 中的当年日期(整数)。
timestamp('2021-08-17T08:24:58Z').getDayOfYear()

结果:

228
$t.getMonth() 以基于零的索引形式返回时间戳记 $t 中的月份(整数)。
timestamp('2021-08-17T08:24:58Z').getMonth()

结果:

7
$t.getFullYear() 返回时间戳记 $t 中的年份(整数)。
timestamp('2021-08-17T08:24:58Z').getFullYear()

结果:

2021
$t.getHours() 返回时间 $t 戳中的小时数,结果为整数。
timestamp('2021-08-17T08:24:58Z').getHours()

结果:

8
$t.getMinutes() 返回时间戳记 $t 中的分钟数(整数)。
timestamp('2021-08-17T08:24:58Z').getMinutes()

结果:

24
$t.getSeconds() 返回时间戳记 $t 中的秒数(整数)。
timestamp('2021-08-17T08:24:58Z').getSeconds()

结果:

58
$t.getMilliseconds() 返回时间戳记 $t 中的毫秒数(整数)。
timestamp('2021-08-17T08:24:58.642Z').getMilliseconds()

结果:

642
int($t) 将时间戳转换为 int64 自 UNIX® 纪元以来的秒数。
int(timestamp('2021-08-17T08:24:58Z'))

结果:

1629188698
duration($d) 持续时间 $d 必须以用 "s" 结尾的字符串形式给出,s 表示以秒计的持续时间。
timestamp('2021-08-17T08:24:58Z') + duration('3600s')

结果:

"2021-08-17T09:24:58Z"
formatTime($t, $s) 以格式 $s 返回时间戳记 $t。 必须以所需格式使用参考时间“2015年1月 $s02-January-06 星期一 15:04:05(山地标准时间)”。
formatTime(timestamp('2021-08-17T08:24:58Z'), 'Monday, 02-Jan-06 15:04:05 MST')

结果:

"Tuesday, 17-August-21 08:24:58 UTC"

表8。 URI 编码和解码函数
语法 描述 示例
encodeURI($uri) 返回一个字符串,表示将给定的字符串 $uri 编码为 URI 后的结果。 A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #此方法会转义所有字符,但以下字符除外:.
encodeURI('test.html?name=Jürgen&car=audi')

结果:

"test.html?name=J%C3%BCrgen&car=audi"
decodeURI($uri) $uri返回一个字符串,表示对编码 URI 的解码结果。
decodeURI('test.html?name=J%C3%BCrgen&car=audi')

结果:

"test.html%3Fname%3DJ%C3%BCrgen%26car%3Daudi"
encodeURIComponent($uri) 返回一个字符串,该字符串表示将给定的字符串 $uri 编码为 URI 组件后的结果。 A-Z a-z 0-9 - _ . ! ~ * ' ( )此方法会转义所有字符,但以下字符除外:.
encodeURI('test.html?name=Jürgen&car=audi')

结果:

"test.html%3Fname%3DJ%C3%BCrgen%26car%3Daudi"
decodeURIComponent($uri) $uri返回一个字符串,表示该编码 URI 组件的解码版本。
decodeURIComponent('test.html%3Fname%3DJ%C3%BCrgen%26car%3Daudi')

结果:

"test.html?name=Jürgen&car=audi"

UUID 函数

语法 描述 示例
genUUID() 根据 RFC 4122 以及 DCE 1.1: 身份验证和安全服务生成一个 UUID。
genUUID()

结果:

4eb1a3f3-5461-4b91-8d69-69e25f2a1b6a

类型与转换函数

语法 描述 示例
type($value) $value返回. 的类型。
type(1234)

结果:"int"

type("hello")

结果:

"string"
bool($string) 将字符串 $string 转换为布尔值。 "True"true 允许取值为 "true"、 和 "TRUE"

"False"false 允许取值为 "false"、 和 "FALSE"

bool("true")

结果:

true

bool("FALSE")

结果:

false
bytes($string) 将字符串 $string 转换为字节。
bytes("Hello")

结果:

"aGVsbG8="
double($value) 将该值 $value 转换为 double 类型。 该 $value 类型可以是以下其中一种:int、uint 或 string。
double(10)/4.0

结果:

2.5

double("3.14")

结果:

3.14

int($value) 将该值 $value 转换为整数。 该 $value 类型可以是以下类型之一:double、uint、string、enum 或 timestamp。 如果提供了时间戳,返回的值是自 Unix 纪元以来的秒数。
int(10.0/4)

结果:

2

int(3.14)

结果:

3

int("123")

结果:

123

int(now)

结果:

1742801032
uint($value) 将该值 $value 转换为无符号整数。 该 $value 类型可以是以下其中一种:double、int 或 string。
uint(3.14)

结果:

3

uint("123")

结果:

123
string($value) 将该值 $value 转换为字符串。 该 $value 类型可以是以下类型之一:bool、int、uint、double、bytes、timestamp 或 duration。 如果提供了持续时间,该值将转换为秒和秒的分数部分,并在后缀处添加“s”。 如果提供了时间戳,该值将转换为 RFC3339 格式。
string(true)

结果:

"true"

string(1234)

结果:

"1234"
string(b'helllo')

结果:

"hello"
string(duration('1m100ms'))

结果:

"60.1s"

string(now)

结果:

"2025-03-24T07:42:51Z"

HTTP 客户机

可以编写属性函数以调用外部 API 端点来获取值。
注意:
  • 授权头令牌必须由使用者生成。 例如,其可以是一个返回到函数的长期存在的 API 密钥。
语法 描述 示例
hc.Get($url, $headers)

返回状态码、响应头和响应正文。如果内容类型为 application/json,响应正文将以 JSON 对象的形式返回;如果是其他内容类型,则以字符串形式返回。 $url: URL API 端点的地址必须是完整的 URL

{"headerName":"headerVal"}$headers: JSON 表单中的对象。

hc.Get("https://api.jke.com/resources/" + user.name.givenName, {"Authorization":"Some token"})

结果:

{"statusCode": "200", "responseHeaders": {"header": ["value1", "value2"]}, "responseBody": {"value":"someValue"}}

hc.GetAsString($url, $headers) 将响应作为序列化字符串返回。 API 端点的 $url: URL 必须是完整 URL $headers: JSON 对象(格式为 {"headerName":"headerVal"})。
hc.GetAsString("https://api.jke.com/resources/" + user.name.givenName, {"Authorization":"Some token"})

结果:

"{\"value\":\"someValue\"}"

hc.GetAsJson($url, $headers) 将响应解析为 JSON 对象。 API 端点的 $url: URL 必须是完整 URL $headers: JSON 对象(格式为 {"headerName":"headerVal"})。
hc.GetAsJson("https://api.jke.com/resources/" + user.name.givenName, {"Authorization":"Some token"}).value

结果:

"someValue"

hc.Post($url, $headers, $body) 返回状态码、响应标头和响应主体,如果内容类型为 application/json,那么响应主体将作为 JSON 对象返回,或者作为任何其他内容类型的字符串返回。

$url - API 端点的 URL 必须是完整的 URL。

$headers - 格式为 {"headerName":"headerVal"} 的 JSON 对象

$body - 请求字符串形式的主体。

hc.Post("https://api.jke.com/resources", {"Authorization": "Some token"}, "{\"key\":\"value\"}")

结果:

{"statusCode": "200", "responseHeaders": {"header": ["value1", "value2"]}, "responseBody": {"message": "success"}}

hc.Patch($url, $headers, $body) 返回状态码、响应头和响应正文。如果内容类型为 application/json,响应正文将作为 JSON 对象返回;如果是其他内容类型,则作为字符串返回。

$url: API 端点的 URL 必须是完整的 URL。

{"headerName":"headerVal"}$headers: 格式为 JSON 对象。

$body: 以字符串形式呈现的请求正文。

hc.Patch("https://api.jke.com/resources", {"Authorization": "Some token"}, "{\"key\":\"value\"}")

结果:

{"statusCode": "200", "responseHeaders": {"header": ["value1", "value2"]}, "responseBody": {"message": "success"}}

hc.Put($url, $headers, $body) 返回状态码、响应头和响应正文。如果内容类型为 application/json,响应正文将以 JSON 对象的形式返回;如果是其他内容类型,则以字符串形式返回。

$url: API 端点的 URL 必须是完整的 URL。

{"headerName":"headerVal"}$headers: 格式为 JSON 对象。

$body: 以字符串形式呈现的请求正文。

hc.Put("https://api.jke.com/resources", {"Authorization": "Some token"},
      "{\"key\":\"value\"}")

结果:

{"statusCode": "200", "responseHeaders": {"header": ["value1", "value2"]}, "responseBody": {"message": "success"}}
hc.Delete($url, $headers) 返回状态码、响应头和响应正文。 如果内容类型为 application/JSON,响应正文将以 JSON 对象的形式返回;如果是其他内容类型,则返回字符串。

$url: API 端点的 URL 必须是完整的 URL。

$headers: 表单中的 JSON 对象

{"headerName":"headerVal"}
hc.Delete("https://api.jke.com/resources", {"Authorization": "Some token"})

结果:

{"statusCode": "200", "responseHeaders": {"header": ["value1", "value2"]}, "responseBody": {"message": "success"}}

hc.Opts($options) 当前支持$options: 八个标志:
  1. insecure: 表示 SSL 连接可能不安全。
  2. certLabel: 已上载到 CI 租户的签署者证书的标签。
  3. tlsMinVersion: 受支持的最低 TLS 版本。 可用选项为 TLSv1.0、TLSv1.1 和 TLSv1.2。 如果未指定此标志,那么最低 TLS 版本将设置为 TLSv1.2。
  4. followRedirects: 指示 HTTP 客户机是否遵循重定向。 如果未指定值,那么设置将缺省为 false
  5. cache: 布尔值,指示是否缓存响应。 对于 GET 调用,此设置缺省为 true,对于其他 HTTP 方法,此设置缺省为 false。
  6. cacheExpiry: 缓存响应的生存期(以秒为单位),最大值为 1 小时 (3600)。 如果未指定生存期,那么设置将缺省为 60 秒。
  7. mtls:指示是否应该对请求启用相互 TLS 的布尔值。 如果将该值设置为 true,那么将忽略以下标志的值:insecure、certLabel、tlsMinVersion 和 followRedirects。
  8. mtlsCert:要针对 MTLS 请求提供的现有个人证书的标签。
此函数以 hc 实例进行响应,因此可以调用 GetAsJSONGetAsString
hc.Opts({"certLabel": "jkeCA","insecure":false,
"tlsMinVersion":"TLSv1.2", "followRedirects":true,"cache":true,
"cacheExpiry":"1200"}).GetAsString(...)
注意: 每个请求的响应正文大小上限为 4 MB。
URL 限制
提供给 HTTP 客户端的 API 端点的 URL 必须是以 $protocol://$host[:$port]. 开头的完整 URL 格式。
  1. 该字段 $protocol 必须为“http”或“https”。
  2. $host 名称必须是一个完全合格的域名(FQDN)。 不允许使用IP地址。
  3. 端口号 $port 是可选的。 HTTP 客户端支持以下端口。 使用任何其他端口都会导致超时。
    • 端口 80、443 和 8088
    • 端口范围 7000-7050
    • 端口范围 8000-8050
HTTP 客户机响应缓存

缺省情况下,对于 GET 调用(GetAsStringGetAsJSON)启用 HTTP 响应缓存,缺省缓存到期时间为 1 分钟。 对于 POST 调用,缺省情况下会将其禁用。 要覆盖 HTTP 客户机响应缓存的缺省设置,标志 cache 必须包含在 hc.Opts 中,其值为 truefalse。 缺省情况下,缓存生存期设置为 60 秒。 要覆盖缺省缓存生存期,标志 cacheExpiry 必须包含在 hc.Opts 中,其值以秒为单位,最多为 3600 秒(1 小时)。

适应性风险

使用自适应访问风险函数来访问当前用户会话风险级别和关联的授权数据。

使用定制属性之前,必须在会话中对自适应访问策略至少求值一次,以确保填充数据,否则将返回值 “NOT_AVAILABLE”

自适应访问风险函数可访问“策略编辑器”中显示的相应访问策略条件,具体请参阅《 管理自适应访问策略规则 》。

风险指标的详细信息在 “风险提示 ”中进行了说明。

风险数据的关键指标被构造为 JSON,可以在以下示例中看到。 可以通过使用 risk.getAdaptiveSessionData() 函数访问此 JSON 结构。

与用户会话相关的完整自适应风险数据响应可以通过使用 risk.getRawAdaptiveSessionData() 函数进行访问。

{
  "riskLevel": "LOW", 
  "isNewDevice": false, 
  "isRiskyDevice": false, 
  "isRiskyConnection": false, 
  "remoteIP": "122.143.222.333", 
  "country": "ISR", 
  "city": "Jerusalem", 
  "isp": "013 Netvision", 
  "isNewLocation": false, 
  "behavioralAnomaly": false,
  "userBehavioralScore":"100"
}
语法 描述 示例
risk.getAdaptiveSessionLevel() 该函数返回用户会话的自适应风险等级。
risk.getAdaptiveSessionLevel()

结果:

"LOW"

risk.getAdaptiveSessionData() 返回与用户会话相关的自适应风险数据的 JSON 数组。 具有前缀 is 的属性将返回布尔值。 所有其他特性返回字符串。
risk.getAdaptiveSessionData()

结果:

"behavioralAnomaly":false, 
"city":"Bundall", 
"country":"AUS", 
"isNewDevice":false, 
"isNewLocation":false, 
"isRiskyConnection":false, 
"isRiskyDevice":false, 
"isp":"Network Technology (AUST) P/L", 
"remoteIP":"120.29.43.158", 
"riskLevel":"LOW",
"userBehavioralScore":"100"
risk.getAdaptiveSessionData().($p) risk.getAdaptiveSessionData()该函数从 中返回该属性 $p
risk.getAdaptiveSessionData().isRiskyDevice

结果:

true
risk.getAdaptiveSessionData().isp

结果:

"Network Technology (AUST) P/L”

注意: 在应用程序的属性映射中使用提取的自适应属性,或在访问策略评估中的自定义属性条件时,可能需要进行数据类型转换,包括将 JSON 转换为 string.

例如:

要在访问策略中返回字符串值以 risk_score 供评估,必须先将其强制转换为字符串。

 string(risk.getRawAdaptiveSessionData()[1].message.pinpoint_assessment.risk.risk_score)

要在“高级”规则中执行数学或逻辑运算或求值,必须先将 JSON 数字强制转换为 int

 int(risk.getRawAdaptiveSessionData()[1].message.pinpoint_assessment.risk.risk_score) > 900
或评估为双精度值
 risk.getRawAdaptiveSessionData()[1].message.pinpoint_assessment.risk.risk_score > 900.0

应用程序

在某些使用场景(如资源配置和对账)中,该 app 对象可在 CELx 规则中使用。 该对象表示用于账户同步的应用程序 JSON。

app 对象在规则中可被视为一个独立的映射,并且还提供了以下辅助方法。
语法 描述 示例
app.getSupportingData() 返回该应用程序的辅助数据。
app.getSupportingData()

结果:

<JSON object representing supporting data>

OAuth

语法 描述 示例
oauth.GetBearerToken($url, $clientId, $clientSecret) 该函数使用 client_credentials 授权类型调用指定的令牌端点 $url ,并提供 clientId $clientId和 clientSecret$clientSecret ,若调用成功,则返回访问令牌。
oauth.GetBearerToken("https://api.jke.com/token", "123456-abcd-efgh-9876-q1w2e3r4t5y6", "secret")

结果:

15PSJF576qi2LF658k30I1WLTwGOw2Vzage2AtiS

JWT 函数

语法 描述 示例
jwt.sign($payload, $headers) 该函数生成一个带签名的 JSON Web Token(JWT)。 该函数接受两个参数:
  • $payload: 此处包含有效载荷,该有效载荷应为一个 JSON 对象。
  • alg$headers: 其中包含标题,例如 kidtyp、 等。 该 kid 标签是加载到 Verify 租户中的个人证书的标签。
注: 默认行为:
  • 如果 kid 未在标头中提供,则使用租户中的默认个人证书对 JWT 进行签名。
  • 如果 alg 标头中未提供,系统将使用 RS256 对JWT进行签名。
jwt.sign({'key1': 'value1', 'auth': ['lval3', 'lval4'], 'iat': 1696567390}, {'alg':'RS256','kid':'cert1'})

结果:

eyJhb...<truncated>...J6d5EzIU-ldnemMV75Q

调试功能

调试函数可用于同时求解表达式并生成跟踪日志。 如果在启用跟踪模式的情况下执行某条规则,系统将生成跟踪日志。 有关启用跟踪模式和查看跟踪日志的更多信息,请参阅 《创建流程 》和《 管理跟踪视图》 中的“跟踪设置”部分。

语法 描述 示例
debug($expr, $logString) 评估表达式 $expr 并生成调试日志 $logString

该函数接受两个参数:

  • $expr: 待求值的表达式。
  • $logString: 将生成的日志字符串。 它可以是一个表达式,且其计算结果应始终为字符串。 $expr$logString 应包含字符串 $value,该字符串用于替换通过求值获得的值。
debug("jessica@jke.com".split("@")[1], "The email domain is $value")

结果:

jke.com

还将生成以下跟踪日志:“”The email domain is jke.com

debug($expr, $logString, $metadata) 评估表达式 $expr ,并生成包含额外自定义元数据的调试日志 $logString

该函数接受三个参数:

  • $expr: 待求值的表达式。
  • $logString: 将生成的日志字符串。 它可以是一个表达式,且其计算结果应始终为字符串。 $expr$logString 应包含字符串 $value,该字符串用于替换通过求值获得的值。
  • $metadata: 随日志一起发送的自定义元数据,以键值对映射的形式提供。 每对键值的值可以是一个表达式,该表达式必须求值为字符串。
debug("jessica@jke.com".split("@")[1], "The email domain is $value", {"flow":
      "login", "time": string(now)})

结果:

jke.com
还将生成以下跟踪日志:"The email domain is jke.com",其中包含以下元数据字段:
  • "flow": "login"
  • "time": "< timestamp >"

缓存函数

缓存函数可用于利用 Rule 服务中的缓存。 缓存功能主要分为两种类型:基于会话的和非基于会话的。 基于会话的缓存函数使用 session,而非基于会话的缓存函数使用 cache。 使用基于会话的缓存函数存储在缓存中的值与用户会话相关联。

整体缓存(会话缓存和非会话缓存)有最大容量限制。 此限制可能会因租户的配置而有所不同。 一旦缓存已满,任何向缓存添加条目的请求都将导致错误。

缓存函数的结果格式如下——
{
  "isSuccessful": true/false, //indicates if the operation was successful or not
  "value": "<string>", // the value obtained from the operation
  "errorID": "<string>", // the error ID if any
  "errorMessage": "<string>", // the error message if any
}
表9。 基于会话的缓存功能
语法 描述 示例
session.Set($key, $value $ttlSec) 将与用户会话相关的值存储在缓存中。

该函数接受三个参数:

  • $key:缓存中使用的键。 它可以是一个表达式,且其计算结果应始终为字符串。 该密钥的最大长度为 16 个字符。
  • $value:待存储的值。 它可以是一个表达式,且其计算结果应始终为字符串。 该值的最大长度为 1000000 个字符。
  • $ttlSec:该值的生存时间。 最大值为28800。
session.Set("computedID", "user1@web.com", "1200")
结果:

{"result":{"isSuccessful":true}}
session.Get($key) 获取缓存中与该用户会话关联的 $key 值。
session.Get("computedID")
结果:

{"result":{"isSuccessful":true, "value": "user1@web.com"}}
session.Delete($key) 从缓存中移除与该用户会话关联的 $key 值。
session.Delete("computedID")
结果:

{"result":{"isSuccessful":true}}
session.Exists($key) 检查缓存中是否存在与用户会话关联的项 $key
session.Exists("computedID")
结果:

{"result":{"isSuccessful":true, "value":"true"}}
session.GetAndDelete($key) 获取缓存中与该用户会话关联的 $key 值,并将其从缓存中移除。
session.GetAndDelete("computedID")
结果:

{"result":{"isSuccessful":true, "value": "user1@web.com"}}
表10。 非会话型缓存函数
语法 描述 示例
cache.Set($key, $value $ttlSec) 将一个值存储在缓存中。
该函数接受 3 个参数:
  • $key:缓存中使用的键。 它可以是一个表达式,且其计算结果应始终为字符串。 该密钥的最大长度为 16 个字符。
  • $value:待存储的值。 它可以是一个表达式,且其计算结果应始终为字符串。 该值的最大长度为 1000000 个字符。
  • $ttlSec:该值的生存时间。 最大值为 604800。
cache.Set("companyName", "DunderMifflin", "1200")

结果:

{"result":{"isSuccessful":true}}
cache.Get($key) 获取缓存中具有该 $key 值的项。
cache.Get("companyName")
结果:

{"result":{"isSuccessful":true, "value": "DunderMifflin"}}
cache.Delete($key) 从缓存中移除带有 的 $key 值。
cache.Delete("companyName")
结果:

{"result":{"isSuccessful":true}}
cache.Exists($key) 检查缓存中是否存在该项 $key
cache.Exists("companyName")
结果:

{"result":{"isSuccessful":true, "value":"true"}}
cache.GetAndDelete($key) 获取缓存中具有该 $key 值的条目,并将其从缓存中移除。
cache.GetAndDelete("companyName")
结果:

{"result":{"isSuccessful":true, "value": "DunderMifflin"}}
表 11。 常见错误情况
错误 结果
密钥长度超出限制
{"error":{"messageId":"CSIBU2000E","messageDescription":"The length of the
              key provided exceeds the character limit of [16]."}}}
该值的长度超出了限制
{"error":{"messageId":"CSIBU2000E","messageDescription":The length of the
              value provided for the key [exampleKey] exceeds the character limit of
              [1000000]."}}}
从缓存中获取密钥时未找到该密钥
{"result":{"errorID":"CSIBU2040E","errorMessage":"Failed to get a value from
              the cache with the key [exampleKey].","isSuccessful":false}}
当缓存限制被超过时
{"error":{"messageId":"CSIBU2000E","messageDescription":"Cache limit has
              been exceeded."}}

“秘密”功能

使用密钥函数来访问现有密钥。
注: CELx 表达式中的“Secrets”( VDEV_66277 )功能可根据要求启用。 如需申请此功能,请联系您的 IBM 销售代表或 IBM 联系人,并表明您希望启用此功能的意愿。 如果您有权限创建支持工单,请创建一个工单,并在工单主题中注明“CELx 表达式中的密钥”。 IBM Verify 试用订阅用户无法创建支持工单。
语法 描述 示例
secrets.get($group, $name) 获取指定 $group 组和名称的密码 $name secrets.get("apiKeys", "testKey")

结果:

<the testKey secret in the apiKeys group>
secrets.get($name) $name获取指定名称的密钥。 “秘密”组的默认组名为“default”。 secrets.get("testKey")

结果:

<the testKey secret in the default group>