Ejemplo n.º 1
0
        /// <summary>
        /// Generates a "personal access token" or service specific, usage restricted access token.
        /// <para/>
        /// Returns a "personal access token" for the user if successful; otherwise `<see langword="null"/>`.
        /// </summary>
        /// <param name="targetUri">The target resource for which to acquire the personal access token for.</param>
        /// <param name="accessToken">Azure Directory access token with privileges to grant access to the target resource.</param>
        /// <param name="options">Set of options related to generation of personal access tokens.</param>
        protected async Task <Credential> GeneratePersonalAccessToken(
            TargetUri targetUri,
            Token accessToken,
            PersonalAccessTokenOptions options)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }
            if (accessToken is null)
            {
                throw new ArgumentNullException(nameof(accessToken));
            }

            TokenScope requestedScope = TokenScope;

            if (options.TokenScope != null)
            {
                // Take the intersection of the authority scope and the requested scope
                requestedScope &= options.TokenScope;

                // If the result of the intersection is none, then fail
                if (string.IsNullOrWhiteSpace(requestedScope.Value))
                {
                    throw new InvalidOperationException("Invalid scope requested. Requested scope would result in no access privileges.");
                }
            }

            Credential credential = null;

            Token personalAccessToken;

            if ((personalAccessToken = await Authority.GeneratePersonalAccessToken(targetUri, accessToken, requestedScope, options.RequireCompactToken, options.TokenDuration)) != null)
            {
                credential = (Credential)personalAccessToken;

                Trace.WriteLine($"personal access token created for '{targetUri}'.");

                try
                {
                    await PersonalAccessTokenStore.WriteCredentials(targetUri, credential);
                }
                catch (Exception exception)
                {
                    System.Diagnostics.Debug.WriteLine(exception);

                    Trace.WriteLine($"failed to write credentials to the secure store: {exception.GetType().Name}.");
                }
            }

            return(credential);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates an interactive logon session, using ADAL secure browser GUI, which enables users to authenticate with the Azure tenant and acquire the necessary access tokens to exchange for a VSTS personal access token.
        /// <para/>
        /// Tokens acquired are stored in the secure secret stores provided during initialization.
        /// <para/>
        /// Return a `<see cref="Credential"/>` for resource access if successful; otherwise `<see langword="null"/>`.
        /// </summary>
        /// <param name="targetUri">The URI of the VSTS resource.</param>
        public async Task <Credential> InteractiveLogon(TargetUri targetUri, PersonalAccessTokenOptions options)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);

            try
            {
                Token token;
                if ((token = await Authority.InteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl), null)) != null)
                {
                    Trace.WriteLine($"token acquisition for '{targetUri}' succeeded.");

                    return(await GeneratePersonalAccessToken(targetUri, token, options));
                }
            }
            catch (AuthenticationException)
            {
                Trace.WriteLine($"token acquisition for '{targetUri}' failed.");
            }

            Trace.WriteLine($"interactive logon for '{targetUri}' failed");
            return(null);
        }
        /// <summary>
        /// Opens an interactive logon prompt to acquire an authentication token from the Microsoft Live authentication and identity service.
        /// <para/>
        /// Returns a `<see cref="Credential"/>` for packing into a basic authentication header; otherwise `<see langword="null"/>`.
        /// </summary>
        /// <param name="targetUri">
        /// The uniform resource indicator of the resource access tokens are being requested for.
        /// </param>
        /// <param name="options"></param>
        public async Task <Credential> InteractiveLogon(TargetUri targetUri, PersonalAccessTokenOptions options)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);

            try
            {
                Token token;
                if ((token = await Authority.InteractiveAcquireToken(targetUri, ClientId, Resource, new Uri(RedirectUrl), QueryParameters)) != null)
                {
                    Trace.WriteLine($"token '{targetUri}' successfully acquired.");

                    return(await GeneratePersonalAccessToken(targetUri, token, options));
                }
            }
            catch (AdalException exception)
            {
                Debug.Write(exception);
            }

            Trace.WriteLine($"failed to acquire token for '{targetUri}'.");
            return(null);
        }
        public static async Task <Credential> QueryCredentials(Program program, OperationArguments operationArguments)
        {
            if (program is null)
            {
                throw new ArgumentNullException(nameof(program));
            }
            if (operationArguments is null)
            {
                throw new ArgumentNullException(nameof(operationArguments));
            }
            if (operationArguments.TargetUri is null)
            {
                var innerException = new NullReferenceException($"{operationArguments.TargetUri} cannot be null.");
                throw new ArgumentException(innerException.Message, nameof(operationArguments), innerException);
            }

            BaseAuthentication authentication = await program.CreateAuthentication(operationArguments);

            Credential credentials = null;

            switch (operationArguments.Authority)
            {
            default:
            case AuthorityType.Basic:
            {
                var basicAuth = authentication as BasicAuthentication;

                // Attempt to get cached credentials or acquire credentials if interactivity is allowed.
                if ((operationArguments.Interactivity != Interactivity.Always &&
                     (credentials = await authentication.GetCredentials(operationArguments.TargetUri)) != null) ||
                    (operationArguments.Interactivity != Interactivity.Never &&
                     (credentials = await basicAuth.AcquireCredentials(operationArguments.TargetUri)) != null))
                {
                    program.Trace.WriteLine("credentials found.");
                    // No need to save the credentials explicitly, as Git will call back
                    // with a store command if the credentials are valid.
                }
                else
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                    program.LogEvent($"Failed to retrieve credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                }
            }
            break;

            case AuthorityType.AzureDirectory:
            {
                var aadAuth    = authentication as Vsts.AadAuthentication;
                var patOptions = new Vsts.PersonalAccessTokenOptions()
                {
                    RequireCompactToken = true,
                    TokenDuration       = operationArguments.TokenDuration,
                    TokenScope          = null,
                };

                // Attempt to get cached credentials -> non-interactive logon -> interactive
                // logon note that AAD "credentials" are always scoped access tokens.
                if (((operationArguments.Interactivity != Interactivity.Always &&
                      ((credentials = await aadAuth.GetCredentials(operationArguments.TargetUri)) != null) &&
                      (!operationArguments.ValidateCredentials ||
                       await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) ||
                    (operationArguments.Interactivity != Interactivity.Always &&
                     ((credentials = await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, patOptions)) != null) &&
                     (!operationArguments.ValidateCredentials ||
                      await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) ||
                    (operationArguments.Interactivity != Interactivity.Never &&
                     ((credentials = await aadAuth.InteractiveLogon(operationArguments.TargetUri, patOptions)) != null) &&
                     (!operationArguments.ValidateCredentials ||
                      await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))))
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                    program.LogEvent($"Azure Directory credentials  for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                }
                else
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                    program.LogEvent($"Failed to retrieve Azure Directory credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                }
            }
            break;

            case AuthorityType.MicrosoftAccount:
            {
                var msaAuth    = authentication as Vsts.MsaAuthentication;
                var patOptions = new Vsts.PersonalAccessTokenOptions()
                {
                    RequireCompactToken = true,
                    TokenDuration       = operationArguments.TokenDuration,
                    TokenScope          = null,
                };

                // Attempt to get cached credentials -> interactive logon note that MSA
                // "credentials" are always scoped access tokens.
                if (((operationArguments.Interactivity != Interactivity.Always &&
                      ((credentials = await msaAuth.GetCredentials(operationArguments.TargetUri)) != null) &&
                      (!operationArguments.ValidateCredentials ||
                       await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) ||
                    (operationArguments.Interactivity != Interactivity.Never &&
                     ((credentials = await msaAuth.InteractiveLogon(operationArguments.TargetUri, patOptions)) != null) &&
                     (!operationArguments.ValidateCredentials ||
                      await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials))))
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                    program.LogEvent($"Microsoft Live credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                }
                else
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                    program.LogEvent($"Failed to retrieve Microsoft Live credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                }
            }
            break;

            case AuthorityType.GitHub:
            {
                var ghAuth = authentication as Github.Authentication;

                if ((operationArguments.Interactivity != Interactivity.Always &&
                     ((credentials = await ghAuth.GetCredentials(operationArguments.TargetUri)) != null) &&
                     (!operationArguments.ValidateCredentials ||
                      await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) ||
                    (operationArguments.Interactivity != Interactivity.Never &&
                     ((credentials = await ghAuth.InteractiveLogon(operationArguments.TargetUri)) != null) &&
                     (!operationArguments.ValidateCredentials ||
                      await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))))
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                    program.LogEvent($"GitHub credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                }
                else
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                    program.LogEvent($"Failed to retrieve GitHub credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                }
            }
            break;

            case AuthorityType.Bitbucket:
            {
                var bbcAuth = authentication as Bitbucket.Authentication;

                if (((operationArguments.Interactivity != Interactivity.Always) &&
                     ((credentials = await bbcAuth.GetCredentials(operationArguments.TargetUri, operationArguments.Username)) != null) &&
                     (!operationArguments.ValidateCredentials ||
                      ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.Username, credentials)) != null))) ||
                    ((operationArguments.Interactivity != Interactivity.Never) &&
                     ((credentials = await bbcAuth.InteractiveLogon(operationArguments.TargetUri, operationArguments.Username)) != null) &&
                     (!operationArguments.ValidateCredentials ||
                      ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.Username, credentials)) != null))))
                {
                    program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                    // Bitbucket relies on a username + secret, so make sure there is a
                    // username to return.
                    if (operationArguments.Username != null)
                    {
                        credentials = new Credential(operationArguments.Username, credentials.Password);
                    }
                    program.LogEvent($"Bitbucket credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                }
                else
                {
                    program.LogEvent($"Failed to retrieve Bitbucket credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                }
            }
            break;

            case AuthorityType.Ntlm:
            {
                program.Trace.WriteLine($"'{operationArguments.TargetUri}' is NTLM.");
                credentials = BasicAuthentication.NtlmCredentials;
            }
            break;
            }

            if (credentials != null)
            {
                operationArguments.Credentials = credentials;
            }

            return(credentials);
        }