50.3. OAuth 验证器回调 #
OAuth 验证器模块通过定义一组回调来实现其功能。服务器会按需调用这些回调,以处理来自用户的认证请求。
50.3.1. 启动回调 #
startup_cb 回调在模块加载后立即执行。该回调用于建立本地状态、定义自定义 HBA 选项,并在需要时执行额外初始化。若验证器模块需要保存状态,可使用 state->private_data
存储。
typedef void (*ValidatorStartupCB) (ValidatorModuleState *state);
50.3.2. 校验回调 #
validate_cb 回调在 OAuth 交换过程中执行,即用户尝试使用 OAuth 进行认证时。之前调用中设置的任何状态都可通过
state->private_data 访问。
typedef bool (*ValidatorValidateCB) (const ValidatorModuleState *state,
const char *token, const char *role,
ValidatorModuleResult *result);
token 包含待校验的 Bearer 令牌。PostgreSQL 已保证该令牌在语法上格式正确,但尚未执行任何其他校验。role 包含用户请求登录的角色。回调必须在 result 结构体中设置输出参数,其定义如下:
typedef struct ValidatorModuleResult
{
bool authorized;
char *authn_id;
char *error_detail;
} ValidatorModuleResult;
仅当模块将 result->authorized
设为 true 时,连接才会继续。为完成用户认证,已认证用户名(由令牌确定)应通过 palloc 分配,并在 result->authn_id 字段中返回。另一种情况是:若令牌有效但无法确定关联用户身份,可将 result->authn_id 设为 NULL。如果验证器返回 true 并设置了 result->authn_id,那么当 log_connections 包含 authentication 时,该身份会出现在服务器日志中。这发生在授权之前,因此即使连接后来因授权而被拒绝,也会记录认证。
验证器可返回 false 以表示内部错误,此时连接失败。否则,验证器应返回 true,表示其已处理该令牌并作出授权决策。
在验证错误或内部错误这两种失败情况下,模块都可以在
result->error_detail 中保存一段供用户阅读的失败原因。这会作为认证失败的 DETAIL 条目打印到服务器日志中(不会发送给客户端)。error_detail 指向的内存可以是 palloc
分配的,也可以是静态存储期内存。成功时会忽略 error_detail。
validate_cb 返回后的行为取决于具体 HBA 配置。在常规情况下,result->authn_id 中的用户名必须与用户要登录的角色完全匹配(该行为可通过用户名映射修改)。但如果根据启用了 delegate_ident_mapping
的 HBA 规则进行认证,PostgreSQL 不会对
result->authn_id 的值做任何检查;此时由验证器负责确保令牌具备足够权限,以便用户能以指定的 role 登录。
50.3.3. 关闭回调 #
shutdown_cb 回调在服务器后端完成对该连接的令牌验证后执行。如果验证器模块分配了状态,该回调应释放相关资源以避免资源泄漏。
typedef void (*ValidatorShutdownCB) (ValidatorModuleState *state);