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;
}