/// <summary>
        /// Handles the authentication.
        /// </summary>
        /// <returns>An authenticate result.</returns>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            var signatureHeader = Request.Headers["X-LC-Signature"].SingleOrDefault();
            var algoHeader      = Request.Headers["X-LC-Signature-Algo"].SingleOrDefault();
            var timeHeader      = Request.Headers["X-LC-Transmission-Time"].SingleOrDefault();
            var tenantHeader    = Request.Headers["X-LC-Tenant"].SingleOrDefault();

            var tenant = await _tenantProvider.GetTenantSecret(tenantHeader);

            if (tenant == null || string.IsNullOrEmpty(tenant.TenantId) || string.IsNullOrEmpty(tenant.PublicKey))
            {
                return(AuthenticateResult.Fail("Could not authenticate."));
            }

            var path     = Request.Path.Value + Request.QueryString;
            var contents = await Request.BodyReader.ReadAsync();

            // Reset the request body stream position
            Request.Body.Position = 0;
            var isVerifiedSignature = ValidateSignature(timeHeader, tenantHeader, path, algoHeader, signatureHeader, tenant.PublicKey, contents.Buffer.ToArray());

            if (!isVerifiedSignature)
            {
                return(AuthenticateResult.Fail("Could not authenticate."));
            }

            var claims = new[] {
                new Claim("X-LC-Tenant", tenantHeader)
            };
            var identity  = new ClaimsIdentity(claims, Scheme.Name);
            var principal = new ClaimsPrincipal(identity);
            var ticket    = new AuthenticationTicket(principal, Scheme.Name);

            return(AuthenticateResult.Success(ticket));
        }