全部產品
Search
文件中心

Identity as a Service:進階賬戶欄位運算式

更新時間:Dec 17, 2025

本文詳細介紹了如何在IDaaS的內建運算式引擎中使用進階賬戶欄位運算式,以及詳細的模型欄位說明、函數說明及相應的參考樣本。

基礎說明

IDaaS內建了運算式引擎,在SAML和OIDC應用中,支援使用進階運算式,向返回使用者資訊中添加新的參數。當目標應用需接受額外參數,且參數需要進行某種轉化、拼接、判斷時,可使用運算式實現。

與此類似,可以使用同樣方法,在配置與身份提供方間同步的欄位對應時,也可使用運算式實現欄位值自訂賦值。

本篇文檔下方列有參考樣本,協助快速理解運算式使用情境和方法。​

以OIDC為例,在SSO配置中,支援擴充返回的id_token資訊。在擴充值中,可填寫進階運算式full_phone,以達成特定處理目標。

image.png

更多使用方式請參考:SAML Attribute Statements值填寫規範OIDC id_token擴充值填寫規範欄位管理

運算式分為兩部分:

  • 模型,包含User(對應IDaaS賬戶)和AppUser(對應應用賬戶)兩種。

  • 函數,代表執行邏輯關係。

模型說明

1. User

下欄欄位在IDaaS的User模型中,可使用類似user.usernameuser.lockExpireTime 的引用方式。

字段显示名称

字段标识

数据类型

是否必填

是否唯一

用户侧权限

說明

賬戶 ID

userId

字串

可見

使用者ID。

賬戶名

username

字串

可見

使用者名稱。

顯示名稱

displayName

字串

可編輯

使用者顯示名稱。

郵箱

email

字串

可編輯

郵箱。

手機

phoneNumber

數字

可編輯

手機號。

手機區號

phoneRegion

數字

可編輯

手機地區編號,樣本:中國區號為 "86",不帶 "00" 或 "+"。

外部 ID

userExternalId

字串

可見

使用者外部ID。

來源類型

userSourceType

字串

可見

來源類型,取值為:

  • build_in:自建。

  • ding_talk:DingTalk。

  • ad:AD。

  • ldap:LDAP。

  • we_com:企業微信。

  • lark:飛書。

  • idp_auto_build:IDP自動建立。

來源 ID

userSourceId

字串

可見

來源ID。

賬戶狀態

status

字串

可見

使用者狀態,取值為:

  • enabled:啟用。

  • disabled:禁用。

描述

description

字串

可見

描述。

賬戶到期時間

accountExpireTime

數字

可見

使用者到期時間,UNIX時間戳記,單位毫秒。

賬戶註冊時間

registerTime

數字

可見

使用者註冊時間,UNIX時間戳記,單位毫秒。

密碼到期時間

passwordExpireTime

數字

可見

密碼到期時間,UNIX時間戳記,單位毫秒。

鎖定到期時間

lockExpireTime

數字

可見

鎖定到期時間,UNIX時間戳記,單位毫秒。

建立時間

createTime

數字

可見

建立時間,UNIX時間戳記,單位毫秒。

更新時間

updateTime

數字

可見

最近一次更新使用者資訊的時間,UNIX時間戳記,單位毫秒。

2. App User

下欄欄位在IDaaS的AppUser模型中,可使用類似appUser.username引用方式。

屬性

說明

username

應用帳號使用者名稱。

3. IdP User

IdP User模型應用於與身份提供方進行同步時,舉例:DingTalk的辦公地點欄位:idpUser.work_place

具體欄位請查看對應身份提供方文檔,例如DingTalk的DingTalk協助文檔-使用者詳情

重要

對於OIDC身份提供方(參考綁定OIDC身份提供方),在自動綁定能力中使用運算式時,僅id_token中的sub、phoneNumber、email欄位的首碼使用idpUser.,例如idpUser.sub;其餘欄位的首碼需使用idpUser.rawUserInfo.,例如idpUser.rawUserInfo.aud

函數說明

以下為我們開放的對應的函數及樣本:

函數名

函數定義

說明

舉例

Append

Append(str1, str2, ..., strn)

拼接輸入參數為新的字串,等於str1+str2+...

  • 輸入:Append("str1", "@example.com")

  • 輸出: str1@example.com

Join

Join(source1, source2, ..., sourceN, separator)

將多個源值拼接為一個字串,源值間用分隔字元分隔。

  • 輸入:Join("str1", "str2", 123,"-")

  • 輸出:"str1-str2-123"

Coalesce

Coalesce(source1, source2, ..., sourceN, defaultValue)

返回輸入參數中第一個不允許為 NULL 的參數,若參數都為空白,則返回null,其中非空指非null且參數長度大於0。

  • 輸入:Coalesce("", user.phoneRegion, "86")

  • 輸出:當手機號區號為空白即缺失時,輸出為 86

IIF

IIF(condition, whenTrue, whenFalse)

三目運算。根據condition的結果返回不同的值,為true時返回whenTrue,為false時返回whenFalse。

樣本1:

  • 輸入:IIF(true, 1, 2)

  • 輸出:1

樣本2:

  • 輸入:IIF(false, 1, 2)

  • 輸出:2

IsNull

IsNull(value)

當value為null即缺失時,輸出為true。

樣本1:

  • 輸入:IsNull(null)

  • 輸出:輸出為true

樣本2:

  • 輸入:IsNull("")

  • 輸出:輸出為false

IsNullOrEmpty

IsNullOrEmpty(value)

當value為null或Null 字元串時,輸出為true。

樣本1:

  • 輸入:IsNullOrEmpty(user.email)

  • 輸出:當郵箱為null即缺失時,輸出為true

樣本2:

  • 輸入:IsNullOrEmpty("")

  • 輸出:輸出為true

Now

Now()

返回表示當前UTC DateTime的字串,格式為 yyyy-MM-dd'T'HH:mm:ssXXX。

  • 輸出:2021-11 01T09:52:11Z

StringReplace

StringReplace("hello $VariableName", "$VariableName", ReplaceString)

一般字元串替換。

  • 輸入:StringReplace("hello $str", "$str", "world")

  • 輸出:hello world

Trim

Trim(source)

去除源值字串前後的空白字元。

  • 輸入:Trim(" 123 ")

  • 輸出:123

TrimLeft

TrimLeft(source)

去除源值字串左側的空白字元。

  • 輸入:TrimLeft(" 123 ")

  • 輸出:123

TrimRight

TrimRight(source)

去除源值字串右側的空白字元。

  • 輸入:TrimRight(" 123 ")

  • 輸出: 123

ToLower

ToLower(source)

字串變為全大寫或全小寫。

  • 輸入:ToLower(" Abc ")

  • 輸出:abc

ToUpper

ToUpper(source)

字串變為全大寫。

  • 輸入:ToUpper(" Abc ")

  • 輸出:ABC

Substring

Substring(source, fromIndex, endIndex)

返回字串的子字串,即子字串下標地址為 [fromIndex, endIndex]。

  • source:必須,源字串,可為文法支援的任意類型。

  • fromIndex:必須,整數類型。非整型時返回null。

  • endIndex:必須,整數類型。非整型時返回null。

樣本1:

  • 輸入:Substring("0123456", 1, 5)

  • 輸出:1234

樣本2:

  • 輸入:Substring("0123456", -1, 7)

  • 輸出:0123456

樣本3:

  • 輸入:Substring("0123456", "1", 5)

  • 輸出:null

SubstringBefore

SubstringBefore(source, subString)

返回源字串中從左至右匹配到的第一個目標字串後的字串。若目標字串不存在,則返回null。

參數:

  • source:必須,源字串,可為文法支援的任意類型。

  • target:必須,目標字串,可為文法支援的任意類型。

傳回值:string

樣本1:

  • 輸入:SubstringBefore("test@example@com", "@")

  • 輸出:"test"

Array

Array(source1, source2,...)

將多個值組合成為數組。值可為Object類型。

  • 輸入:Array(1, 2, 3)

  • 輸出:[1, 2, 3]

ArrayAdd

ArrayAdd(Array(), "test")

在數組對象中添加一個數組。

  • 輸入:ArrayAdd(Array(), "test")

  • 輸出:["test"]

ArrayMap

ArrayMap($ArrayObject, __item.ObjectProperty)

取數組對象中的某個屬性的值形成新的數組。

取使用者中所屬組的ID列表:

  • 輸入:ArrayMap(user.groups, __item.groupId)

  • 輸出:["groupId1","groupId2","groupId3"]

ArrayIndex

ArrayIndex(Array(), n)

取Array第幾個元素,從0開始。

  • 輸入:ArrayIndex(Array(1,2,3), 0)

  • 輸出:1

ArrayJoin

ArrayJoin(Array(), str)

數組以某個字串拼接。

  • 輸入:ArrayJoin(Array(1,2,3), "-")

  • 輸出:"1-2-3"

Object

Object(key1, value1, key2, value2, ...)

通過制定索引值對組合成為Object對象。

支援零個或偶數個參數。

  • 輸入 Object("key1", "value1", "key2", "value2")

  • 輸出對應對象:

{"key1": "value1", "key2": "value2"}

ObjectIndex

ObjectIndex(user, "username")

指定對象的某個屬性的值

代碼 ObjectIndex(user, "username") 等價於 user.username

ObjectToJsonString

ObjectToJsonString(user.groups)

對象轉JSON字串。

-

Contains

Contains(str1,str2)

判斷是否包含,返回true,false。

樣本1:

  • 輸入:Contains("test", "t")

  • 輸出:true

樣本2:

  • 輸入:Contains("test", "a")

  • 輸出:false

Or

Or(true,false,...,true)

或的方式判斷多個條件,有一個條件為true,則為true。

樣本1:

  • 輸入:Or(true,false)

  • 輸出:true

樣本2:

  • 輸入:Or(true,true,false)

  • 輸出:true

樣本3:

  • 輸入:Or(false,false)

  • 輸出:false

And

And(true,false,...,true)

且的方式判斷多個條件,有一個條件為false,則為false。

樣本1:

  • 輸入:And(true,false)

  • 輸出:false

樣本2:

  • 輸入:And(true,true,false)

  • 輸出:false

樣本3:

  • 輸入:And(true,true,true)

  • 輸出:true

xOr

xOr(true,false,...,true)

有且只能有2個條件。

如果都為true或者都為false,則返回false。

如果同時存在true,false的條件,則返回true。

樣本1:

  • 輸入:xOr(true,false)

  • 輸出:true

樣本2:

  • 輸入:xOr(true,true)

  • 輸出:false

樣本3:

  • 輸入:And(false,false)

  • 輸出:false

StartsWith

StartsWith(str1, str2)

判斷字串以...開頭,只能包含2個參數。

樣本1:

  • 輸入:StartsWith("test", "t")

  • 輸出:true

樣本2:

  • 輸入:StartsWith("test", "e")

  • 輸出:false

Split

Split("str1,str2,str3")

字串分割後,返回一個數組。

樣本1:

  • 輸入:Split("str1,str2,str3",",")

  • 輸出:Array(str1,str2,str3)

Equals

Equals(str1,str2)

比較2個字串是否一致。

Equals(str1,str2)。

Equals(str1,str2,false) 不忽略大小寫比較。

Equals(str1,str2,true) 忽略大小寫比較。

樣本1:

  • 輸入:Equals("test","Test")

  • 輸出:false

樣本2:

  • 輸入:Equals("test","Test",true)

  • 輸出:true

樣本3:

  • 輸入:Equals("test","Test",false)

  • 輸出:false

CurrentTimeMillis

CurrentTimeMillis()

目前時間UNIX時間戳記,單位毫秒。

-

SamlArray

SamlArray(Array())

僅SAML SSO可用。

輸入:

SamlArray(Array("group1","group2"))

  • SAML Response輸出:

<saml2:Attribute Name="grouIdArray"

NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">

<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:type="xsd:string">

group1

</saml2:AttributeValue>

<saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">

group2

</saml2:AttributeValue>

  • 輸入:SamlArray(Array("group1","group2"))

  • SAML Response輸出:

</saml2:Attribute>

ExtractPhoneRegion

ExtractPhoneRegion(source, defaultRegion,autoAppendPlusSignal)

提取手機號中的區號。

  • source: 手機號。

  • autoAppendPlusSignal:是否自動補充+號。true為自動補充,false為不補充。

  • defaultRegion:手機區號預設的國家或地區。國家或地區的編碼請參考ISO 3166 Country Codes標準,使用Alpha-2 code(https://www.iso.org/obp/ui/#search)。如CN,US,TW等。

    • 如果手機號裡面攜帶了區號,並且區號前面有+號,可以不傳入autoAppendPlusSignal和deafaultRegion。

    • 如果手機號裡面攜帶區號,但區號前沒有+號,需要傳入autoAppendPlusSignal=true,defaultRegion為預設的國家或地區編碼。

    • 如果手機號裡面不攜帶區號,想要設定預設區號,需要傳入autoAppendPlusSignal=false,defaultRegion為預設的國家或地區編碼。

樣本1:

如果手機號為:+86131xxxxx000+86 131xxxxx000, +86-131xxxxx000

  • 輸入:ExtractPhoneRegion(idpUser.mobile)

  • 返回:86

樣本2:

如果手機號為86131xxxxx00086 131xxxxx000, 86-131xxxxx000

  • 輸入:ExtractPhoneRegion(idpUser.mobile,"CN",true)

  • 返回:86

樣本3:

如果手機號為131xxxxx000

  • 輸入:ExtractPhoneRegion(idpUser.mobile,"CN",false)

  • 返回:86

ExtractPhoneNumber

ExtractPhoneNumber(source, defaultRegion,autoAppendPlusSignal)

提取手機號中的真實手機號(不含區號)。

  • source: 手機號。

  • autoAppendPlusSignal:是否自動補充+號。true為自動補充,false為不補充。

  • defaultRegion:手機區號預設的國家或地區。國家或地區的編碼請參考ISO 3166 Country Codes標準,使用Alpha-2 code(https://www.iso.org/obp/ui/#search)。如CN,US,TW等。

    • 如果手機號裡面攜帶了區號,並且區號前面有+號,可以不傳入autoAppendPlusSignal和deafaultRegion。

    • 如果手機號裡面攜帶區號,但區號前沒有+號,需要傳入autoAppendPlusSignal=true,defaultRegion為預設的國家或地區編碼。

    • 如果手機號裡面不攜帶區號,想要設定預設區號,需要傳入autoAppendPlusSignal=false,defaultRegion為預設的國家或地區編碼。

樣本1:

如果手機號為:+86131xxxxx000+86 131xxxxx000, +86-131xxxxx000

  • 輸入:ExtractPhoneNumber(idpUser.mobile)

  • 返回:131xxxxx000

樣本2:

如果手機號為:86131xxxxx00086 131xxxxx000, 86-131xxxxx000

  • 輸入:ExtractPhoneNumber(idpUser.mobile,"CN",true)

  • 返回:131xxxxx000

樣本3:

如果手機號為:131xxxxx000

  • 輸入:ExtractPhoneNumber(idpUser.mobile,"CN",false)

  • 返回:131xxxxx000

參考樣本

效果

運算式樣本

取使用者名稱,拼接固定 "@example.com"。

Append(user.username, "@example.com")

當郵箱不為空白,返回郵箱。

當郵箱為空白時,取手機號。

Coalesce(user.email, user.phoneNumber)

當手機號為空白時,預設填寫固定手機號。

IIF(IsNullOrEmpty(user.phoneNumber), "1888888****", user.phoneNumber)

將手機號地區和手機號以 - 拼接。

Join(user.phoneRegion, user.phoneNumber, "-")

返回包含顯示名稱的自訂歡迎資訊。

StringReplace("hello $DisplayName", "$DisplayName", user.displayName)

將手機號中間四位用 * 脫敏返回。

Append(

SubString(user.phoneNumber, 0, 4),

"****",

SubString(user.phoneNumber, 8, 10)

)

提取郵箱中的使用者名稱。

SubstringBefore(user.email, "@")

組裝SCIM規範中數組格式的email欄位。

Array(Object("email", user.email, "type", "work", "primary", true))

User模型JSON樣本:

{
  "customFieldMap": {
        "place": {
            "fieldName": "place",
            "fieldValue": "beijing"
        },
        "age": {
            "fieldName": "age",
            "fieldValue": "18"
        }
    },
    "identityProviderUserMap": {
        "idp_m2gngriuenktdkxxxxxx": {
            "identityProviderId": "idp_m2gngriuenktdkxxxxxx",
            "identityProviderType": "ding_talk",
            "identityProviderExternalId": "corp_1234xxxxxxx",
            "identityProviderUserId": "b2ed5fc0xxxxx"
        }
    },
    "organizationalUnits": [
        {
            "organizationalUnitId": "ou_sdfadtaaxxxxxx",
            "organizationalUnitName": "name_001",
            "primary": false
        },
        {
            "organizationalUnitId": "ou_werttxxxxxx",
            "organizationalUnitName": "name_002",
            "primary": true
        }
    ],
    "primaryOrganizationalUnitId": "ou_werttxxxxxx",
    "customFields": [
        {
            "fieldName": "place",
            "fieldValue": "beijing"
        },
        {
            "fieldName": "age",
            "fieldValue": "18"
        }
    ],
    "groups": [
        {
            "groupId": "group_jp6al4sn4n4wjgjxxxxxx",
            "groupName": "group1",
            "groupExternalId": "group_jp6al4sn4n4wjgjxxxxxx"
        },
        {
            "groupId": "group_vavikcxewkf5h3oxxxxxx",
            "groupName": "group2",
            "groupExternalId": "group_vavikcxewkf5h3oxxxxxx"
        }
    ],
  "userId": "user_x3zyd6cxxxxxxxxxxxxx",
  "username": "name_001",
  "displayName": "displayname_001",
  "passwordSet": true,
  "phoneRegion": "86",
  "phoneNumber": "333xxxx3333",
  "phoneNumberVerified": true,
  "email": "xxxxx@example.com",
  "emailVerified": true,
  "userExternalId": "b2ed5fc0xxxxxxxxxx",
  "userSourceType": "ding_talk",
  "userSourceId": "corp_1234xxxxxxx",
  "status": "enabled",
  "accountExpireTime": "-1",
  "passwordExpireTime": "-1",
  "registerTime": "1730454581598",
  "lockExpireTime": "-1",
  "createTime": "1730454582379",
  "updateTime": "1733479455307"
}