private async Task <AuthorizationCodeRedeemedNotification> RunAuthorizationCodeRedeemedNotificationAsync(OpenIdConnectMessage message, OpenIdConnectTokenEndpointResponse tokenEndpointResponse)
        {
            Logger.LogDebug(Resources.OIDCH_0042_AuthorizationCodeRedeemed, message.Code);
            var authorizationCodeRedeemedNotification = new AuthorizationCodeRedeemedNotification(Context, Options)
            {
                Code                  = message.Code,
                ProtocolMessage       = message,
                TokenEndpointResponse = tokenEndpointResponse
            };

            await Options.Notifications.AuthorizationCodeRedeemed(authorizationCodeRedeemedNotification);

            if (authorizationCodeRedeemedNotification.HandledResponse)
            {
                Logger.LogVerbose(Resources.OIDCH_0043_AuthorizationCodeRedeemedNotificationHandledResponse);
            }
            else if (authorizationCodeRedeemedNotification.Skipped)
            {
                Logger.LogVerbose(Resources.OIDCH_0044_AuthorizationCodeRedeemedNotificationSkipped);
            }
            return(authorizationCodeRedeemedNotification);
        }
        private async Task <AuthenticationTicket> HandleCodeOnlyFlow(OpenIdConnectMessage message, AuthenticationProperties properties)
        {
            AuthenticationTicket ticket = null;
            JwtSecurityToken     jwt    = null;

            OpenIdConnectTokenEndpointResponse tokenEndpointResponse = null;
            string idToken = null;
            var    authorizationCodeReceivedNotification = await RunAuthorizationCodeReceivedNotificationAsync(message, properties, ticket, jwt);

            if (authorizationCodeReceivedNotification.HandledResponse)
            {
                return(authorizationCodeReceivedNotification.AuthenticationTicket);
            }
            else if (authorizationCodeReceivedNotification.Skipped)
            {
                return(null);
            }

            // Redeeming authorization code for tokens
            Logger.LogDebug(Resources.OIDCH_0038_Redeeming_Auth_Code, message.Code);

            tokenEndpointResponse = await RedeemAuthorizationCodeAsync(message.Code, authorizationCodeReceivedNotification.RedirectUri);

            idToken = tokenEndpointResponse.Message.IdToken;

            var authorizationCodeRedeemedNotification = await RunAuthorizationCodeRedeemedNotificationAsync(message, tokenEndpointResponse);

            if (authorizationCodeRedeemedNotification.HandledResponse)
            {
                return(authorizationCodeRedeemedNotification.AuthenticationTicket);
            }
            else if (authorizationCodeRedeemedNotification.Skipped)
            {
                return(null);
            }

            // no need to validate signature when token is received using "code flow" as per spec [http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation].
            var validationParameters = Options.TokenValidationParameters.Clone();

            validationParameters.ValidateSignature = false;

            ticket = ValidateToken(idToken, message, properties, validationParameters, out jwt);

            if (Options.GetClaimsFromUserInfoEndpoint)
            {
                Logger.LogDebug(Resources.OIDCH_0040_Sending_Request_UIEndpoint);
                ticket = await GetUserInformationAsync(properties, tokenEndpointResponse.Message, ticket);
            }

            var securityTokenValidatedNotification = await RunSecurityTokenValidatedNotificationAsync(message, ticket);

            if (securityTokenValidatedNotification.HandledResponse)
            {
                return(securityTokenValidatedNotification.AuthenticationTicket);
            }
            else if (securityTokenValidatedNotification.Skipped)
            {
                return(null);
            }

            // If id_token is received using code only flow, no need to validate chash.
            await ValidateOpenIdConnectProtocolAsync(jwt, message, false);

            return(ticket);
        }