Exemplo n.º 1
0
        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}"));
        }
Exemplo n.º 2
0
        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();
                }
            }
        }