DocuSign Connect webhook call did not include HMAC header x-docusign-signature

不问归期 提交于 2020-05-29 17:02:32

问题


In my account, I created a Connect webhook configuration. I added a secret key and also checked the Include HMAC signature checkbox.

After I signed an envelope, DocuSign Connect called my API.

It sent a successful request body but it did not send the expected request header x-docusign-signature.

Reference: the Connect HMAC configuration page

I got following request header from 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]
}

Thank you for your help.


回答1:


Currently, the documentation on HMAC authentication is seriously misleading as it suggests you simply enable it in the admin part of the site.

You will also need to set the 'IncludeHMAC' setting in the EventNotification part of the envelope when you send it.

This code is based on the C# DocuSign Client but should be equally applicable to other languages.

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")
        }
    };
}

This is an example of how to authenticate their HMAC signature on the Api side. Example in Web Api / .NET Core but should be easy to translate into Java or the framework of your choice.

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;
        }
    } 

If you're utilising the example in .NET Core / Web Api you will need to enable rewinds on the Http request body. You can implement this functionality using this bit of middleware.

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>();



回答2:


The first HMAC signature header is X-DocuSign-Signature-1, the second one is X-DocuSign-Signature-2 etc.

Many web stacks are case sensitive when the application is looking for the value of a specific header. (I just had this exact same problem in a webhook app earlier this week. :-) )

Also, if you're building a Connect webhook integration, please consider using an asynchronous, microservices architecture. I explain how do this, with complete code examples for AWS, Azure, and Google Cloud.



来源:https://stackoverflow.com/questions/56673644/docusign-connect-webhook-call-did-not-include-hmac-header-x-docusign-signature

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!