DocuSign Connect webhook 调用不包含 HMAC 标头 x-docusign-signature

Bos*_*oss 2 java docusignapi

在我的帐户中,我创建了一个 Connect webhook 配置。我添加了一个密钥并选中了包含 HMAC 签名复选框。

在我签署了一个信封后,DocuSign Connect 调用了我的 API。

它发送了一个成功的请求正文,但没有发送预期的请求标头 x-docusign-signature

参考:Connect HMAC 配置页面

我从 DocuSign 连接获得了以下请求标头。

{host=[qa.****.com], 
 content-type=[text/xml; charset=utf-8], 
 expect=[100-continue], max-forwards=[9], 
 x-forwarded-proto=[https], 
 x-forwarded-port=[443], 
 x-original-host=[qa.****.com], 
 x-original-url=[/****/v1/docusign/webhook/1177/4305], 
 x-forwarded-for=[162.248.186.11:58652, 10.3.0.5], 
 x-arr-ssl=[2048|256|C=US, S=Arizona, L=Scottsdale, O="GoDaddy.com, Inc.", OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2|OU=Domain Control Validated, CN=qa.cloudlex.com], 
 x-arr-log-id=[06ca1160-b70c-41d9-8e8c-6e018983ad94], 
 x-forwarded-host=[qa.****.com], 
 x-forwarded-server=[qa.****.com], 
 connection=[Keep-Alive], content-length=[2184]
}
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助。

Cou*_*ero 6

目前,有关 HMAC 身份验证的文档具有严重的误导性,因为它建议您只需在站点的管理部分启用它。

发送时,您还需要在信封的 EventNotification 部分中设置“IncludeHMAC”设置。

此代码基于 C# DocuSign 客户端,但应该同样适用于其他语言。

public EventNotification BuildEventNotifications(string callbackUrl)
{
    return new EventNotification
    {
        IncludeEnvelopeVoidReason = "true",
        EnvelopeEvents = new List<EnvelopeEvent>
        {
            new EnvelopeEvent("sent", "false"),
            new EnvelopeEvent("delivered", "false"), // When opened
            new EnvelopeEvent("completed", "true"), // When signed 
            new EnvelopeEvent("declined", "false"),
            new EnvelopeEvent("voided", "false")
        },
        Url = callbackUrl,
        LoggingEnabled = "true",
        IncludeHMAC = "true",
        IncludeDocuments = "false",
        RequireAcknowledgment = "true",
        RecipientEvents = new List<RecipientEvent>
        {
            new RecipientEvent("false", "Sent"),
            new RecipientEvent("false", "Delivered"),
            new RecipientEvent("true", "Completed"),
            new RecipientEvent("false", "Declined")
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

这是如何在 Api 端验证其 HMAC 签名的示例。Web Api / .NET Core 中的示例,但应该很容易转换为 Java 或您选择的框架。

public class HMACAuthorization : Attribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            string xmlBody;

            context.HttpContext.Request.Body.Seek(0, SeekOrigin.Begin);
            using (var reader = new StreamReader(context.HttpContext.Request.Body, Encoding.UTF8, true, 1024, true))
            {
                xmlBody = reader.ReadToEnd();
            }

            context.HttpContext.Request.Headers.TryGetValue("X-DocuSign-Signature-1", out var hmacSignature);

            if (!HmacIsValid(ConfigurationSettings.DocuSignHMACKey, xmlBody, hmacSignature)) context.Result = new UnauthorizedResult();
        }

        private static bool HmacIsValid(string hmacKey, string body, string hmacSignature)
        {
            var computedHmac = BuildHmacHash(hmacKey, body);

            var hmacIsValid = computedHmac == hmacSignature;

            return hmacIsValid;
        }

        private static string BuildHmacHash(string hmacKey, string body)
        {
            string hash;

            using (var sha = new HMACSHA256(Encoding.UTF8.GetBytes(hmacKey)))
            {
                hash = Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(body)));
            }

            return hash;
        }
    } 
Run Code Online (Sandbox Code Playgroud)

如果您在 .NET Core / Web Api 中使用该示例,则需要在 Http 请求正文上启用倒带。你可以使用这个中间件来实现这个功能。

public class EnableRequestRewindMiddleware
{
    private readonly RequestDelegate _next;

    public EnableRequestRewindMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        context.Request.EnableRewind();
        await _next(context);
    }
}

app.UseMiddleware<EnableRequestRewindMiddleware>();
Run Code Online (Sandbox Code Playgroud)