/// <summary>
        /// Validate the incoming Auth Header as a token sent from a Bot Framework Channel Service.
        /// </summary>
        /// <param name="authHeader">The raw HTTP header in the format: "Bearer [longString]"</param>
        /// <param name="credentials">The user defined set of valid credentials, such as the AppId.</param>
        /// <param name="channelProvider">The user defined configuration for the channel.</param>
        /// <param name="serviceUrl">The service url from the request</param>
        /// <param name="httpClient">Authentication of tokens requires calling out to validate Endorsements and related documents. The
        /// HttpClient is used for making those calls. Those calls generally require TLS connections, which are expensive to
        /// setup and teardown, so a shared HttpClient is recommended.</param>
        /// <param name="channelId">The ID of the channel to validate.</param>
        /// <returns></returns>
        public static async Task <ClaimsIdentity> AuthenticateChannelToken(string authHeader, ICredentialProvider credentials, IChannelProvider channelProvider, string serviceUrl, HttpClient httpClient, string channelId)
        {
            var channelService = await channelProvider.GetChannelServiceAsync().ConfigureAwait(false);

            var tokenExtractor = new JwtTokenExtractor(httpClient,
                                                       ToBotFromEnterpriseChannelTokenValidationParameters,
                                                       string.Format(AuthenticationConstants.ToBotFromEnterpriseChannelOpenIdMetadataUrlFormat, channelService),
                                                       AuthenticationConstants.AllowedSigningAlgorithms);

            var identity = await tokenExtractor.GetIdentityAsync(authHeader, channelId).ConfigureAwait(false);

            await ValidateIdentity(identity, credentials, serviceUrl).ConfigureAwait(false);

            return(identity);
        }
        /// <summary>
        /// Validate the incoming Auth Header as a token sent from a Bot Framework Channel Service.
        /// </summary>
        /// <param name="authHeader">The raw HTTP header in the format: "Bearer [longString]".</param>
        /// <param name="credentials">The user defined set of valid credentials, such as the AppId.</param>
        /// <param name="channelProvider">The user defined configuration for the channel.</param>
        /// <param name="serviceUrl">The service url from the request.</param>
        /// <param name="httpClient">Authentication of tokens requires calling out to validate Endorsements and related documents. The
        /// HttpClient is used for making those calls. Those calls generally require TLS connections, which are expensive to
        /// setup and teardown, so a shared HttpClient is recommended.</param>
        /// <param name="channelId">The ID of the channel to validate.</param>
        /// <param name="authConfig">The authentication configuration.</param>
        /// <returns>ClaimsIdentity.</returns>
        public static async Task <ClaimsIdentity> AuthenticateChannelToken(string authHeader, ICredentialProvider credentials, IChannelProvider channelProvider, string serviceUrl, HttpClient httpClient, string channelId, AuthenticationConfiguration authConfig)
        {
            if (authConfig == null)
            {
                throw new ArgumentNullException(nameof(authConfig));
            }

            var channelService = await channelProvider.GetChannelServiceAsync().ConfigureAwait(false);

            var tokenExtractor = new JwtTokenExtractor(
                httpClient,
                ToBotFromEnterpriseChannelTokenValidationParameters,
                string.Format(CultureInfo.InvariantCulture, AuthenticationConstants.ToBotFromEnterpriseChannelOpenIdMetadataUrlFormat, channelService),
                AuthenticationConstants.AllowedSigningAlgorithms);

            var identity = await tokenExtractor.GetIdentityAsync(authHeader, channelId, authConfig.RequiredEndorsements).ConfigureAwait(false);

            await ValidateIdentity(identity, credentials, serviceUrl).ConfigureAwait(false);

            return(identity);
        }