DocuSign Connect Webhook调用不包括HMAC标头x-docusign-signature

时间:2019-06-19 18:17:14

标签: java docusignapi

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

我在签名信封后,DocuSign Connect调用了我的API。

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

参考:连接HMAC configuration page

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

{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]
}

谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

当前,有关HMAC身份验证的文档具有严重的误导性,因为它表明您只需在站点的admin部分启用它即可。

发送信封时,还需要在信封的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")
        }
    };
}

这是如何在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;
        }
    } 

如果您在.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>();

答案 1 :(得分:0)

第一个HMAC签名标头是 X-DocuSign-Signature-1 ,第二个是 X-DocuSign-Signature-2 等。

当应用程序正在寻找特定标头的值时,许多Web堆栈都区分大小写。 (本周早些时候,我在一个webhook应用程序中遇到了同样的问题。:-))

此外,如果您要构建Connect Webhook集成,请考虑使用异步微服务架构。我将通过AWSAzureGoogle Cloud的完整代码示例来说明如何做到这一点。