/// <summary>
        /// Returns a ClaimsPrincipal object with the NameIdentifier and Name claims, if the request can be
        /// successfully authenticated based on query string parameter bewit or HTTP Authorization header (hawk scheme).
        /// </summary>
        public async Task <ClaimsPrincipal> AuthenticateAsync()
        {
            string bewit;
            bool   isBewit = Bewit.TryGetBewit(this.request, out bewit);

            if (isBewit)
            {
                Tracing.Information("Bewit Found");
            }

            var authentication = isBewit ?
                                 Bewit.AuthenticateAsync(bewit, now, request, credentialsFunc) :
                                 HawkSchemeHeader.AuthenticateAsync(now, request, credentialsFunc);

            this.result = await authentication;

            if (result.IsAuthentic)
            {
                // At this point, authentication is successful but make sure the request parts match what is in the
                // application specific data 'ext' parameter by invoking the callback passing in the request object and 'ext'.
                // The application specific data is considered verified, if the callback is not set or it returns true.
                bool isAppSpecificDataVerified = this.verificationCallback == null ||
                                                 this.verificationCallback(request, result.ApplicationSpecificData);

                if (isAppSpecificDataVerified)
                {
                    // Set the flag so that Server-Authorization header is not sent for bewit requests.
                    this.isBewitRequest = isBewit;

                    var idClaim   = new Claim(ClaimTypes.NameIdentifier, result.Credential.Id);
                    var nameClaim = new Claim(ClaimTypes.Name, result.Credential.User);

                    var identity = new ClaimsIdentity(new[] { idClaim, nameClaim }, HawkConstants.Scheme);

                    return(new ClaimsPrincipal(identity));
                }
                else
                {
                    Tracing.Information("Invalid Application Specific Data, though authentication is successful.");
                }
            }

            return(Principal.Anonymous);
        }
        /// <summary>
        /// Adds the bewit to the query string of the specified HttpRequestMessage object and 
        /// returns the bewit string.
        /// </summary>
        internal string CreateBewitInternal(IRequestMessage request, DateTime utcNow, int lifeSeconds)
        {
            string appData = null;
            if (options.NormalizationCallback != null)
                appData = options.NormalizationCallback(request);

            var bewit = new Bewit(request, options.CredentialsCallback(),
                                    utcNow, lifeSeconds, appData, options.LocalTimeOffsetMillis);
            string bewitString = bewit.ToBewitString();

            string parameter = String.Format("{0}={1}", HawkConstants.Bewit, bewitString);

            string queryString = request.Uri.Query;
            queryString = String.IsNullOrWhiteSpace(queryString) ? parameter : queryString.Substring(1) + "&" + parameter;
            request.QueryString = queryString;

            return bewitString;
        }