/// <inheritdoc/>
        protected override async Task <AuthenticateResult> HandleAuthenticateAsync()
        {
            return(await Task.Run <AuthenticateResult>(() =>
            {
                if (!Request.Headers.ContainsKey("Authorization"))
                {
                    _responseHeader = "Bearer realm=\"token_required\"";
                    _responseResult = ErrorObjectResultFactory.NoAuthorizationHeader();
                    return AuthenticateResult.Fail(_responseResult.Error.Message);
                }

                var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
                if (authHeader.Scheme != "Bearer")
                {
                    _responseHeader = "Bearer error=\"invalid_request\"";
                    _responseResult = ErrorObjectResultFactory.InvalidAuthorizationScheme();
                    return AuthenticateResult.Fail(_responseResult.Error.Message);
                }

                try
                {
                    if (authHeader.Parameter == null)
                    {
                        _responseHeader = "Bearer error=\"invalid_token\"";
                        _responseResult = ErrorObjectResultFactory.InvalidAuthorizationToken();
                        return AuthenticateResult.Fail(_responseResult.Error.Message);
                    }

                    var accessToken = _authorizeService.GetAccessToken(authHeader.Parameter);
                    if (accessToken == null)
                    {
                        _responseHeader = "Bearer error=\"invalid_token\"";
                        _responseResult = ErrorObjectResultFactory.InvalidAuthorizationToken();
                        return AuthenticateResult.Fail(_responseResult.Error.Message);
                    }

                    if (accessToken.ExpiryTime < DateUtil.Now)
                    {
                        _responseHeader = "Bearer error=\"invalid_token\"";
                        _responseResult = ErrorObjectResultFactory.AuthorizationTokenExpired();
                        return AuthenticateResult.Fail(_responseResult.Error.Message);
                    }

                    var result = new List <Claim>();

                    foreach (var role in accessToken.Roles)
                    {
                        result.Add(new Claim(ClaimTypes.Role, role));
                    }

                    foreach (var scope in accessToken.Scopes)
                    {
                        result.Add(new Claim(Scopes.ClaimType, scope));
                    }

                    result.Add(new Claim(ClaimTypes.Name, accessToken.Name));
                    result.Add(new Claim(ClaimTypes.NameIdentifier, accessToken.PrincipalId.ToString()));

                    var identity = new ClaimsIdentity(result.ToArray(), Scheme.Name);
                    var principal = new ClaimsPrincipal(identity);
                    var ticket = new AuthenticationTicket(principal, Scheme.Name);

                    return AuthenticateResult.Success(ticket);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, ex.Message);
                    _responseResult = ErrorObjectResultFactory.InternalServerError();
                    return AuthenticateResult.Fail(_responseResult.Error.Message);
                }
            }));
        }