阻塞事件¶
阻塞事件会在操作执行之前触发,例如在创建用户之前触发。这让您可以通过编程方式中止或修改操作。
在更改持久化到数据库之前,这些事件会同步发送给您的 Hook。
事件列表:
- user.pre_create
- user.profile.pre_update
- user.pre_schedule_deletion
- user.pre_schedule_anonymization
- authentication.pre_initialize
- authentication.post_identified
- authentication.pre_authenticated
- oidc.jwt.pre_create
- oidc.id_token.pre_create
您的 Hook 必须返回一个 JSON 文档,以表明操作是否应该继续。例如,要让操作继续执行,请返回以下 JSON:
每个 Hook 必须在 5 秒内响应。所有 Hook 必须在 10 秒内完成。否则,投递会因超时而失败。
JSON 响应中支持的字段:
| 参数 | 说明 | 支持的阻塞事件 |
|---|---|---|
is_allowed | 允许或中止当前操作 | 所有阻塞事件 |
reason | (当 is_allowed 为 false 时)用于说明拒绝该操作原因的可读文本,会显示在界面上。 | 所有阻塞事件 |
title | (当 is_allowed 为 false 时)用于拒绝该操作的可读标题,会显示在界面上。 | 所有阻塞事件 |
mutation | 修改事件负载中的对象。 | user.pre_create user.profile.pre_update user.pre_schedule_deletion user.pre_schedule_anonymization oidc.jwt.pre_create |
constraints | 为身份验证应用所需的验证约束。例如,要求此次请求使用邮箱 OTP 双重验证。 | authentication.pre_initialize authentication.post_identified authentication.pre_authenticated |
rate_limits | 动态覆盖速率限制权重。 | authentication.pre_initialize authentication.post_identified authentication.pre_authenticated |
bot_protection | 决定是否为此次请求启用机器人防护。 | authentication.pre_initialize authentication.post_identified |
使用 "is_allowed" 拒绝访问¶
要让操作继续执行,请返回一个将 is_allowed 设置为 true 的 JSON 文档。
要中止操作,请返回一个将 is_allowed 设置为 false,并包含非空 reason 和 title 的 JSON 文档。
只要有任何一个 Hook 中止了操作,该操作就会被中止。reason 和 title 会作为错误消息显示给终端用户。
变更(Mutations)¶
对于某些阻塞事件,您的 Hook 可以选择性地应用变更。支持的变更因阻塞事件类型而异。请参阅事件列表了解支持哪些变更。
只有当操作被允许继续执行时,Hook 所做的变更才会被应用;也只有当所有 Hook 都允许操作继续执行时,变更才会生效。
- 未出现在
mutations中的对象保持不变。 - 变更后的对象不会与原始对象合并。
- 变更后的对象不会经过校验,而是沿着 Hook 链继续传递。变更后的对象会在遍历完整个 Hook 链之后才进行校验。
- 为避免无限循环,变更不会产生额外的事件。
用户对象上的变更¶
当某个阻塞事件支持对用户对象进行变更时,您的 Hook 可以在允许操作的 JSON 响应中,指定要对用户对象应用的变更。
{
"is_allowed": true,
"mutations": {
"user": {
"standard_attributes": {
"name": "John"
},
"custom_attributes": {
"age": 30
}
}
}
}
要变更用户对象,请在 mutations 中包含 user。用户对象中只有 standard_attributes、custom_attributes、roles 和 groups 可以被变更。
说明
指定变更时,您必须包含完整的 standard_attributes、custom_attributes、roles 或 groups。否则,缺失的属性将会被删除。
JWT/ID 令牌负载上的变更¶
如果某个阻塞事件支持对访问令牌或 ID 令牌(JWT)负载进行变更,您的 Hook 可以在允许操作的 JSON 响应中,指定要添加到 JWT 负载中的额外字段。但是,您不得更改或删除 JWT 负载中任何已有的字段,因为它们对 JWT 的有效性至关重要。
{
"is_allowed": true,
"mutations": {
"jwt": { // "jwt" for access token or "id_token" for ID Token
"payload": {
// The original payload you get from the event object.
"iss": "https://myapp.authanyid.com",
"aud": ["YOUR_CLIENT_ID"],
"sub": "THE_USER_ID",
// Other essential JWT fields that you MUST retain.
// Additional fields that you want to add.
"https://myapp.com": {
"custom_field": "custom_value"
}
}
}
}
}
要向 JWT 负载添加额外字段,请在 mutations 中包含完整的 jwt.payload。您只能添加自己的自定义字段。
应用身份验证约束¶
使用 constraints 属性,可以为当前请求有条件地要求额外的身份验证方式。
amr:身份验证所需的 Authentication Methods References(AMR,身份验证方法引用)值数组。支持以下取值:pwdotpsmsmfax_primary_passwordx_primary_oob_otp_emailx_primary_oob_otp_smsx_secondary_passwordx_secondary_oob_otp_emailx_secondary_oob_otp_smsx_secondary_totp
当 amr 中返回多个值时,表示这是一个组合要求,用户必须满足所列出的全部验证方式。例如,对于 "amr": ["mfa", "otp"],用户必须在身份验证流程中同时满足 mfa 和 otp。
要求身份验证中使用 MFA 的示例响应:
约束会根据身份验证流程的类型强制执行:
- 注册 / Promote:根据
amr的值,强制设置对应的验证器。 - 登录 / 重新验证:根据
amr的值,强制使用对应的验证器。 - 账号找回:无效果(不支持双重验证)
覆盖速率限制¶
在阻塞事件响应中使用 rate_limits 属性,可以动态覆盖速率限制权重。weight 参数定义了后续操作对指定速率限制贡献的数值。默认值为 1。值为 0 表示后续操作不会计入该速率限制。
例如,以下 Hook 响应表示,在下一次操作中,「账号枚举(account enumeration)」速率限制会被双倍计数,也就是说,用户只需一半的尝试次数就会触发该速率限制。
支持以下速率限制:
authentication.general:验证任意凭据,例如密码、OTPauthentication.account_enumeration:检查登录 ID(用户名、邮箱、手机号)是否存在
机器人防护¶
使用 bot_protection 属性可以为此次请求启用或禁用机器人防护。这会覆盖项目的配置。
覆盖机器人防护的示例响应:
这会覆盖您配置中 bot_protection 原有的 mode。支持以下取值:
always:要求验证码never:禁用验证码
阻塞事件列表¶
user.pre_create¶
在用户创建之前发生。用户可以通过注册、以匿名用户身份注册创建,也可以由管理员通过管理台或 Admin API 创建。
此事件支持用户对象上的变更
{
"type": "user.pre_create",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identities": [
{
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
]
}
}
user.profile.pre_update¶
在用户资料更新之前发生。
此事件支持用户对象上的变更
{
"type": "user.profile.pre_update",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"name": "Chris",
"updated_at": 1136171045
}
}
}
}
user.pre_schedule_deletion¶
在账号删除被安排之前发生。
此事件支持用户对象上的变更
{
"type": "user.pre_schedule_deletion",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": true,
"delete_at": "2022-09-30T15:18:19.040081Z",
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
}
}
}
user.pre_schedule_anonymization¶
在账号匿名化被安排之前发生。
此事件支持用户对象上的变更
{
"type": "user.pre_schedule_anonymization",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": true,
"delete_at": "2022-09-30T15:18:19.040081Z",
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
}
}
}
authentication.pre_initialize¶
在任何身份验证流程开始之前发生。
{
"type": "authentication.pre_initialize",
"payload": {
"authentication_context": {
"user": null,
"asserted_authentications": [],
"asserted_identifications": [],
"amr": [],
"authentication_flow": {
"type": "login",
"name": "default"
}
}
}
}
authentication_context对象包含当前身份验证的详细信息。
authentication.post_identified¶
在身份验证过程中识别出身份之后立即发生,例如用户输入邮箱地址、用户名或手机号之后。
{
"type": "authentication.post_identified",
"payload": {
"authentication_context": {
"authentication_flow": {
"type": "login",
"name": "default"
},
"user": { /* The identified user */
"id": "c1397fc7-10ff-4cbd-bdc9-6fd9ae829c86",
"is_anonymized": false,
"is_anonymous": false,
"is_deactivated": false,
"is_disabled": false,
"is_verified": true,
"last_login_at": "2025-05-27T06:32:54.072273Z",
"roles": [],
"groups": [],
"standard_attributes": {
"email": "user@example.com",
"email_verified": true
},
"custom_attributes": {},
"created_at": "2025-05-27T06:32:54.005206Z",
"updated_at": "2025-05-27T06:32:54.066087Z"
},
"asserted_identifications": [
{ /* The identification methods asserted in the current authentication */
"identification": "oauth",
"identity": {
"id": "8f84ed75-5c8b-45c1-b657-b0c65ac3affe",
"claims": {
"email": "user@example.com",
"email_verified": true,
"family_name": "Authgear",
"given_name": "Test",
"https://authgear.com/claims/oauth/provider_alias": "google",
"https://authgear.com/claims/oauth/provider_type": "google",
"https://authgear.com/claims/oauth/subject_id": "1234567",
"name": "Test Authgear"
},
"type": "oauth",
"created_at": "2025-05-27T06:32:54.02264Z",
"updated_at": "2025-05-27T06:32:54.02264Z"
}
}
],
"asserted_authentications": [],
"amr": []
},
"identification": {
"identification": "oauth",
"identity": { /* The identified identity */
"id": "8f84ed75-5c8b-45c1-b657-b0c65ac3affe",
"claims": {
"email": "user@example.com",
"email_verified": true,
"family_name": "Authgear",
"given_name": "Test",
"https://authgear.com/claims/oauth/provider_alias": "google",
"https://authgear.com/claims/oauth/provider_type": "google",
"https://authgear.com/claims/oauth/subject_id": "1234567",
"name": "Test Authgear"
},
"type": "oauth",
"created_at": "2025-05-27T06:32:54.02264Z",
"updated_at": "2025-05-27T06:32:54.02264Z"
}
}
}
}
authentication_context对象包含当前身份验证的详细信息。identification对象包含所输入及识别出的身份的详细信息。
authentication.pre_authenticated¶
在任何身份验证流程完成之前发生。当剩余流程中不再包含以下任意步骤时触发:identify / authenticate / create_authenticator / verify
{
"payload": {
"authentication_context": {
"authentication_flow": {
"type": "login",
"name": "default"
},
"user": { /* The identified user */
"id": "c1397fc7-10ff-4cbd-bdc9-6fd9ae829c86",
"is_anonymized": false,
"is_anonymous": false,
"is_deactivated": false,
"is_disabled": false,
"is_verified": true,
"last_login_at": "2025-05-27T06:32:54.072273Z",
"roles": [],
"groups": [],
"standard_attributes": {
"email": "user@example.com",
"email_verified": true
},
"custom_attributes": {},
"created_at": "2025-05-27T06:32:54.005206Z",
"updated_at": "2025-05-27T06:32:54.066087Z"
},
"asserted_identifications": [ /* The identification methods asserted in the current authentication */
{
"identification": "oauth",
"identity": {
"id": "8f84ed75-5c8b-45c1-b657-b0c65ac3affe",
"claims": {
"email": "user@example.com",
"email_verified": true,
"family_name": "Authgear",
"given_name": "Test",
"https://authgear.com/claims/oauth/provider_alias": "google",
"https://authgear.com/claims/oauth/provider_type": "google",
"https://authgear.com/claims/oauth/subject_id": "1234567",
"name": "Test Authgear"
},
"type": "oauth",
"created_at": "2025-05-27T06:32:54.02264Z",
"updated_at": "2025-05-27T06:32:54.02264Z"
}
},
],
"asserted_authentications": [ /* Authentication methods asserted during the authentication */
{
"authentication": "primary_oob_otp_sms",
"authenticator": {
"id": "2a6f9927-c76c-4112-868a-879547239266",
"type": "oob_otp_sms",
"kind": "primary"
}
}
],
"amr": ["sms", "otp", "x_primary_oob_otp_sms"]
},
}
}
authentication_context对象包含当前身份验证的详细信息。
oidc.jwt.pre_create¶
在访问令牌签发之前发生。使用此事件可以向 JWT 访问令牌添加自定义字段。
此事件支持阻塞事件
{
"type": "oidc.jwt.pre_create",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": true,
"delete_at": "2022-09-30T15:18:19.040081Z",
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"jwt": {
"payload": {
"iss": "https://myapp.authanyid.com",
"aud": ["YOUR_CLIENT_ID"],
"sub": "338deafa-400b-4589-a922-2c92d670b757"
}
}
}
}
oidc.id_token.pre_create¶
在 ID 令牌签发之前发生。使用此事件可以向 OIDC 的 ID 令牌添加自定义字段。
此事件支持阻塞事件
{
"type": "oidc.id_token.pre_create",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": true,
"delete_at": "2022-09-30T15:18:19.040081Z",
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identities": [
// Identities of the user...
],
"id_token": {
"payload": {
"amr": [
"pwd",
"x_primary_password"
],
"aud": [
"CLIENT_ID"
],
"auth_time": 1136171045,
"exp": 1136171045,
"https://authgear.com/claims/user/can_reauthenticate": true,
"https://authgear.com/claims/user/is_anonymous": false,
"https://authgear.com/claims/user/is_verified": true,
"https://authgear.com/claims/user/roles": [],
"iat": 1759930051,
"iss": "AUTHGEAR_ENDPOINT",
"sid": "...",
"sub": "...",
}
}
},
"context": {
// Authentication context
}
}