private static async Task ValidateAsync(ValidateCredentialsContext context)
        {
            var dbContext = context.HttpContext.RequestServices
                            .GetRequiredService <TContext>();
            var normusername = context.Username.ToUpper();

            var user = await dbContext.Users
                       .Where(u => u.NormalizedUserName == normusername)
                       .Select(u => new { u.Id, u.UserName, u.PasswordHash, u.SecurityStamp })
                       .Cacheable(TimeSpan.FromMinutes(5))
                       .FirstOrDefaultAsync();

            if (user == null)
            {
                context.Fail("User not found.");
                return;
            }

            var passwordHasher = context.HttpContext.RequestServices
                                 .GetRequiredService <IPasswordHasher <TUser> >();

            var attempt = passwordHasher.VerifyHashedPassword(
                user: default, // assert that hasher don't need TUser
        /// <summary>
        /// Creates a new instance of the events instance.
        /// </summary>
        /// <returns>A new instance of the events instance.</returns>
        //protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new BasicAuthenticationEvents());

        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            string authorizationHeader = Request.Headers["Authorization"];

            if (string.IsNullOrEmpty(authorizationHeader))
            {
                return(AuthenticateResult.NoResult());
            }

            if (!authorizationHeader.StartsWith(_Scheme + ' ', StringComparison.OrdinalIgnoreCase))
            {
                return(AuthenticateResult.NoResult());
            }

            string encodedCredentials = authorizationHeader.Substring(_Scheme.Length).Trim();

            if (string.IsNullOrEmpty(encodedCredentials))
            {
                const string noCredentialsMessage = "No credentials";
                Logger.LogInformation(noCredentialsMessage);
                return(AuthenticateResult.Fail(noCredentialsMessage));
            }

            try
            {
                string decodedCredentials = string.Empty;
                byte[] base64DecodedCredentials;
                try
                {
                    base64DecodedCredentials = Convert.FromBase64String(encodedCredentials);
                }
                catch (FormatException)
                {
                    const string failedToDecodeCredentials = "Cannot convert credentials from Base64.";
                    Logger.LogInformation(failedToDecodeCredentials);
                    return(AuthenticateResult.Fail(failedToDecodeCredentials));
                }

                try
                {
                    decodedCredentials = Encoding.UTF8.GetString(base64DecodedCredentials);
                }
                catch (Exception ex)
                {
                    const string failedToDecodeCredentials = "Cannot build credentials from decoded base64 value, exception {0} encountered.";
                    var          logMessage = string.Format(CultureInfo.InvariantCulture, failedToDecodeCredentials, ex.Message);
                    Logger.LogInformation(logMessage);
                    return(AuthenticateResult.Fail(logMessage));
                }


                var delimiterIndex = decodedCredentials.IndexOf(':');
                if (delimiterIndex == -1)
                {
                    const string missingDelimiterMessage = "Invalid credentials, missing delimiter.";
                    Logger.LogInformation(missingDelimiterMessage);
                    return(AuthenticateResult.Fail(missingDelimiterMessage));
                }

                var username = decodedCredentials.Substring(0, delimiterIndex);
                var password = decodedCredentials.Substring(delimiterIndex + 1);

                var validateCredentialsContext = new ValidateCredentialsContext(Context, Scheme, Options)
                {
                    Username = username,
                    Password = password
                };

                await Events.ValidateCredentials(validateCredentialsContext);

                if (validateCredentialsContext.Result != null &&
                    validateCredentialsContext.Result.Succeeded)
                {
                    var ticket = new AuthenticationTicket(validateCredentialsContext.Principal, Scheme.Name);
                    return(AuthenticateResult.Success(ticket));
                }

                if (validateCredentialsContext.Result != null &&
                    validateCredentialsContext.Result.Failure != null)
                {
                    return(AuthenticateResult.Fail(validateCredentialsContext.Result.Failure));
                }

                return(AuthenticateResult.NoResult());
            }
            catch (Exception ex)
            {
                var authenticationFailedContext = new BasicAuthenticationFailedContext(Context, Scheme, Options)
                {
                    Exception = ex
                };

                await Events.AuthenticationFailed(authenticationFailedContext);

                if (authenticationFailedContext.Result != null)
                {
                    return(authenticationFailedContext.Result);
                }

                throw;
            }
        }
 public virtual Task ValidateCredentials(ValidateCredentialsContext context) => OnValidateCredentials(context);