public override async Task HandleRequestAsync()

in CredentialProvider.Microsoft/CredentialProviders/Vsts/VstsCredentialProvider.cs [93:182]


        public override async Task<GetAuthenticationCredentialsResponse> HandleRequestAsync(GetAuthenticationCredentialsRequest request, CancellationToken cancellationToken)
        {
            var forceCanShowDialogTo = EnvUtil.ForceCanShowDialogTo();
            var canShowDialog = request.CanShowDialog;
            if (forceCanShowDialogTo.HasValue)
            {
                Logger.Verbose(string.Format(Resources.ForcingCanShowDialogFromTo, request.CanShowDialog, forceCanShowDialogTo.Value));
                canShowDialog = forceCanShowDialogTo.Value;
            }

            var authInfo = await authUtil.GetAuthorizationInfoAsync(request.Uri, cancellationToken);
            Verbose(string.Format(Resources.UsingAuthority, authInfo.EntraAuthorityUri));

            IEnumerable<ITokenProvider> tokenProviders = await tokenProvidersFactory.GetAsync(authInfo.EntraAuthorityUri);
            cancellationToken.ThrowIfCancellationRequested();

            var tokenRequest = new TokenRequest()
            {
                IsRetry = request.IsRetry,
                IsNonInteractive = request.IsNonInteractive,
                CanShowDialog = canShowDialog,
                IsWindowsIntegratedAuthEnabled = EnvUtil.WindowsIntegratedAuthenticationEnabled(),
                LoginHint = EnvUtil.GetMsalLoginHint(),
                InteractiveTimeout = TimeSpan.FromSeconds(EnvUtil.GetDeviceFlowTimeoutFromEnvironmentInSeconds(Logger)),
                DeviceCodeResultCallback = (DeviceCodeResult deviceCodeResult) =>
                {
                    Logger.Minimal(string.Format(Resources.DeviceFlowRequestedResource, request.Uri.ToString()));
                    Logger.Minimal(string.Format(Resources.DeviceFlowMessage, deviceCodeResult.VerificationUrl, deviceCodeResult.UserCode));

                    return Task.CompletedTask;
                },
            };

            // Try each bearer token provider (e.g. cache, WIA, UI, DeviceCode) in order.
            // Only consider it successful if the bearer token can be exchanged for an Azure DevOps token.
            foreach (ITokenProvider tokenProvider in tokenProviders)
            {
                bool shouldRun = tokenProvider.CanGetToken(tokenRequest);
                if (!shouldRun)
                {
                    Verbose(string.Format(Resources.NotRunningBearerTokenProvider, tokenProvider.Name));
                    continue;
                }

                Verbose(string.Format(Resources.AttemptingToAcquireBearerTokenUsingProvider, tokenProvider.Name));

                string bearerToken = null;
                try
                {
                    var result = await tokenProvider.GetTokenAsync(tokenRequest, cancellationToken);
                    bearerToken = result?.AccessToken;
                }
                catch (Exception ex)
                {
                    Verbose(string.Format(Resources.BearerTokenProviderException, tokenProvider.Name, ex));
                    continue;
                }

                if (string.IsNullOrWhiteSpace(bearerToken))
                {
                    Verbose(string.Format(Resources.BearerTokenProviderReturnedNull, tokenProvider.Name));
                    continue;
                }

                Info(string.Format(Resources.AcquireBearerTokenSuccess, tokenProvider.Name));
                Info(Resources.ExchangingBearerTokenForSessionToken);
                try
                {
                    string sessionToken = await vstsSessionTokenProvider.GetAzureDevOpsSessionTokenFromBearerToken(request, bearerToken, tokenProvider.IsInteractive, cancellationToken);

                    if (!string.IsNullOrWhiteSpace(sessionToken))
                    {
                        Verbose(string.Format(Resources.VSTSSessionTokenCreated, request.Uri.AbsoluteUri));
                        return new GetAuthenticationCredentialsResponse(
                            Username,
                            sessionToken,
                            message: null,
                            authenticationTypes: new List<string>() { "Basic" },
                            responseCode: MessageResponseCode.Success);
                    }
                }
                catch (Exception e)
                {
                    Verbose(string.Format(Resources.VSTSCreateSessionException, request.Uri.AbsoluteUri, e.Message, e.StackTrace));
                }
            }

            Verbose(string.Format(Resources.VSTSCredentialsNotFound, request.Uri.AbsoluteUri));
            return null;
        }