通知(回调)验证
更新时间:2024-02-28
百度智能云 RTC 服务可以通过发送通知的方式,向用户指定的服务地址,发送一些关键的事件,比如录制回调。
对于通知功能,客户可以通过开启验证,对通知模板设置密钥,并依据通知请求 header 中字段、body 内容、通知密钥等来判断该通知请求是否是合法请求。
- 由于在百度智能云 RTC 服务中,通知功能往往表现为相关事件回调。如不作特殊说明,本文中通知也可以称作回调。
1. 通知密钥
客户在创建通知时,可以设置开启验证,并设置密钥。
例如,对于录制回调而言,客户可以通过控制台应用管理 -> 应用 -> 回调配置,设置验证类型为签名验证,并设置回调密钥。
2. 开启验证的通知请求
对通知模板设置了开启验证后,百度智能云 RTC 服务在发送通知请求时,会携带如下3个 header:
- notification-auth-user:验证标识,目前固定为客户的百度云账号的 ID;
- notification-auth-expire:通知事件的过期时间戳(并非精准的过期时间,仅用于计算token);
- notification-auth-token:使用特定算法生成的 token,用于客户侧校验通知请求的合法性。
3. notification-auth-token 计算过程
3.1 计算参数解释
- POST:通知请求使用的 http 方法,固定为 POST;
- endpoint:客户设置的用于接收通知的地址。比如对于录制回调而言,endpoint 就是回调地址;
- body:通知请求的 body 内容;
- notification-auth-expire:通知请求的 notification-auth-expire header;
- notification-auth-user:通知请求的 notification-auth-user header;
- authKey:客户设置的通知密钥。对于录制回调而言,authKey 就是回调密钥;
- SHA256-HEX:是一个Hash算法,详见:https://datatracker.ietf.org/doc/html/rfc4868 。
3.2 计算步骤
第一步计算 content。
content=POST;endpoint;body;notification-auth-expire;notification-auth-user
第二步计算 notification-auth-token。
notification-auth-token=SHA256-HEX(authKey,content)
3.3 计算示例
下面给出 Java 语言计算和验证 notification-auth-token 的代码示例,其他语言版本可以自行实现。
(1)引入 apache 工具包
这里借助 apache 工具包来实现 SHA256-HEX 算法,客户也可自行实现。
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.12</version>
</dependency>
(2)验证 notification-auth-token
@RequestMapping(value = "/***", method = RequestMethod.POST)
public boolean process(HttpServletRequest servletRequest, @RequestBody String callbackBody) {
// http header 字段名不区分大小写
String authExpire = servletRequest.getHeader("notification-auth-expire");
String authUser = servletRequest.getHeader("notification-auth-user");
String authToken = servletRequest.getHeader("notification-auth-token");
log.debug("Received callback, authExpire={}, authUser={}, authToken={}, body={}",
authExpire, authUser, authToken, callbackBody);
if (StringUtils.isEmpty(authExpire) || StringUtils.isEmpty(authUser) || StringUtils.isEmpty(authToken)) {
// header 中无相关验证信息,请确认该通知模板是否开启了验证,未开启验证的话无需校验验证信息。
log.debug("Fail to auth callback, error auth params");
return false;
}
// notificationEndpoint 和 authKey 是客户配置的通知地址和通知密钥。
String notificationEndpoint = "http://***/***";
String authKey = "testkey";
String content = String.format("POST;%s;%s;%s;%s", notificationEndpoint, callbackBody, authExpire, authUser);
String generatedToken = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, authKey).hmacHex(content);
log.debug("Generated auth token={}", generatedToken);
if (!authToken.equals(generatedToken)) {
log.debug("Fail to auth callback, token is error");
return false;
}
// token 校验合法,处理通知请求的逻辑省略。。。
return true;
}