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