public async Task <Uri> GetAadAuthorityUriAsync(Uri uri, CancellationToken cancellationToken) { var environmentAuthority = EnvUtil.GetAuthorityFromEnvironment(logger); if (environmentAuthority != null) { return(environmentAuthority); } var headers = await GetResponseHeadersAsync(uri, cancellationToken); var bearerHeaders = headers.WwwAuthenticate.Where(x => x.Scheme.Equals("Bearer", StringComparison.Ordinal)); foreach (var param in bearerHeaders) { if (param.Parameter == null) { // MSA-backed accounts don't expose a parameter continue; } var equalSplit = param.Parameter.Split(new[] { "=" }, StringSplitOptions.RemoveEmptyEntries); if (equalSplit.Length == 2) { if (equalSplit[0].Equals("authorization_uri", StringComparison.OrdinalIgnoreCase)) { if (Uri.TryCreate(equalSplit[1], UriKind.Absolute, out Uri parsedUri)) { logger.Verbose(string.Format(Resources.FoundAADAuthorityFromHeaders, parsedUri)); return(parsedUri); } } } } // Return the common tenant var aadBase = UsePpeAadUrl(uri) ? "https://login.windows-ppe.net" : "https://login.microsoftonline.com"; logger.Verbose(string.Format(Resources.AADAuthorityNotFound, aadBase)); var tenant = EnvUtil.MsalEnabled() ? OrganizationsTenant: CommonTenant; return(new Uri($"{aadBase}/{tenant}")); }
public static async Task <int> Main(string[] args) { CancellationTokenSource tokenSource = new CancellationTokenSource(); var parsedArgs = await Args.ParseAsync <CredentialProviderArgs>(args); var multiLogger = new MultiLogger(); var fileLogger = GetFileLogger(); if (fileLogger != null) { multiLogger.Add(fileLogger); } // Cancellation listener Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs eventArgs) => { // ConsoleCancelEventArgs.Cancel defaults to false which terminates the current process. multiLogger.Verbose(Resources.CancelMessage); tokenSource.Cancel(); }; var authUtil = new AuthUtil(multiLogger); IBearerTokenProvidersFactory bearerTokenProvidersFactory; if (EnvUtil.MsalEnabled()) { var msalTokenProviderFactory = new MsalTokenProviderFactory(); bearerTokenProvidersFactory = new MsalBearerTokenProvidersFactory(multiLogger, msalTokenProviderFactory); } else { var adalTokenCache = AdalTokenCacheUtils.GetAdalTokenCache(multiLogger); var adalTokenProviderFactory = new VstsAdalTokenProviderFactory(adalTokenCache); bearerTokenProvidersFactory = new BearerTokenProvidersFactory(multiLogger, adalTokenProviderFactory); } var vstsSessionTokenProvider = new VstsSessionTokenFromBearerTokenProvider(authUtil, multiLogger); List <ICredentialProvider> credentialProviders = new List <ICredentialProvider> { new VstsBuildTaskServiceEndpointCredentialProvider(multiLogger), new VstsBuildTaskCredentialProvider(multiLogger), new VstsCredentialProvider(multiLogger, authUtil, bearerTokenProvidersFactory, vstsSessionTokenProvider), }; try { IRequestHandlers requestHandlers = new RequestHandlerCollection { { MessageMethod.GetAuthenticationCredentials, new GetAuthenticationCredentialsRequestHandler(multiLogger, credentialProviders) }, { MessageMethod.GetOperationClaims, new GetOperationClaimsRequestHandler(multiLogger, credentialProviders) }, { MessageMethod.Initialize, new InitializeRequestHandler(multiLogger) }, { MessageMethod.SetLogLevel, new SetLogLevelRequestHandler(multiLogger) }, { MessageMethod.SetCredentials, new SetCredentialsRequestHandler(multiLogger) }, }; // Help if (parsedArgs.Help) { Console.WriteLine(string.Format(Resources.CommandLineArgs, Program.Version, Environment.CommandLine)); Console.WriteLine(ArgUsage.GenerateUsageFromTemplate <CredentialProviderArgs>()); Console.WriteLine( string.Format( Resources.EnvironmentVariableHelp, EnvUtil.LogPathEnvVar, EnvUtil.SessionTokenCacheEnvVar, EnvUtil.AuthorityEnvVar, EnvUtil.AdalFileCacheEnvVar, EnvUtil.PpeHostsEnvVar, EnvUtil.SupportedHostsEnvVar, EnvUtil.SessionTimeEnvVar, EnvUtil.TokenTypeEnvVar, EnvUtil.BuildTaskUriPrefixes, EnvUtil.BuildTaskAccessToken, EnvUtil.BuildTaskExternalEndpoints, EnvUtil.AdalTokenCacheLocation, EnvUtil.SessionTokenCacheLocation, EnvUtil.WindowsIntegratedAuthenticationEnvVar, EnvUtil.DeviceFlowTimeoutEnvVar, EnvUtil.ForceCanShowDialogEnvVar, EnvUtil.MsalEnabledEnvVar, EnvUtil.MsalAuthorityEnvVar, EnvUtil.MsalFileCacheEnvVar, EnvUtil.DefaultMsalCacheLocation, EnvUtil.MsalFileCacheLocationEnvVar )); return(0); } // Plug-in mode if (parsedArgs.Plugin) { try { using (IPlugin plugin = await PluginFactory.CreateFromCurrentProcessAsync(requestHandlers, ConnectionOptions.CreateDefault(), tokenSource.Token).ConfigureAwait(continueOnCapturedContext: false)) { multiLogger.Add(new PluginConnectionLogger(plugin.Connection)); multiLogger.Verbose(Resources.RunningInPlugin); multiLogger.Verbose(string.Format(Resources.CommandLineArgs, Program.Version, Environment.CommandLine)); await WaitForPluginExitAsync(plugin, multiLogger, TimeSpan.FromMinutes(2)).ConfigureAwait(continueOnCapturedContext: false); } } catch (OperationCanceledException ex) { // When restoring from multiple sources, one of the sources will throw an unhandled TaskCanceledException // if it has been restored successfully from a different source. // This is probably more confusing than interesting to users, but may be helpful in debugging, // so log the exception but not to the console. multiLogger.Log(LogLevel.Verbose, allowOnConsole: false, ex.ToString()); } return(0); } // Stand-alone mode if (requestHandlers.TryGet(MessageMethod.GetAuthenticationCredentials, out IRequestHandler requestHandler) && requestHandler is GetAuthenticationCredentialsRequestHandler getAuthenticationCredentialsRequestHandler) { // When emitting machine-readable output to standard out, logging (including Device Code prompts) must be emitted to standard error if (parsedArgs.OutputFormat == OutputFormat.Json) { multiLogger.Add(new StandardErrorLogger()); } else { multiLogger.Add(new StandardOutputLogger()); } multiLogger.SetLogLevel(parsedArgs.Verbosity); multiLogger.Verbose(Resources.RunningInStandAlone); multiLogger.Verbose(string.Format(Resources.CommandLineArgs, Program.Version, Environment.CommandLine)); if (parsedArgs.Uri == null) { Console.WriteLine(ArgUsage.GenerateUsageFromTemplate <CredentialProviderArgs>()); return(1); } GetAuthenticationCredentialsRequest request = new GetAuthenticationCredentialsRequest(parsedArgs.Uri, isRetry: parsedArgs.IsRetry, isNonInteractive: parsedArgs.NonInteractive, parsedArgs.CanShowDialog); GetAuthenticationCredentialsResponse response = await getAuthenticationCredentialsRequestHandler.HandleRequestAsync(request).ConfigureAwait(continueOnCapturedContext: false); // Fail if credentials are not found if (response?.ResponseCode != MessageResponseCode.Success) { return(2); } string resultUsername = response?.Username; string resultPassword = parsedArgs.RedactPassword ? Resources.Redacted : response?.Password; if (parsedArgs.OutputFormat == OutputFormat.Json) { // Manually write the JSON output, since we don't use ConsoleLogger in JSON mode (see above) Console.WriteLine(JsonConvert.SerializeObject(new CredentialResult(resultUsername, resultPassword))); } else { multiLogger.Info($"{Resources.Username}: {resultUsername}"); multiLogger.Info($"{Resources.Password}: {resultPassword}"); } return(0); } return(-1); } finally { foreach (ICredentialProvider credentialProvider in credentialProviders) { credentialProvider.Dispose(); } } }