Ejemplo n.º 1
0
        private StringContent GetAccessTokenRequestBody(TargetUri targetUri, TokenScope tokenScope, TimeSpan?duration = null)
        {
            const string ContentBasicJsonFormat = "{{ \"scope\" : \"{0}\", \"displayName\" : \"Git: {1} on {2}\" }}";
            const string ContentTimedJsonFormat = "{{ \"scope\" : \"{0}\", \"displayName\" : \"Git: {1} on {2}\", \"validTo\": \"{3:u}\" }}";
            const string HttpJsonContentType    = "application/json";

            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }
            if (tokenScope is null)
            {
                throw new ArgumentNullException(nameof(tokenScope));
            }

            string tokenUrl = GetTargetUrl(targetUri, false);

            Trace.WriteLine($"creating access token scoped to '{tokenScope}' for '{tokenUrl}'");

            string jsonContent = (duration.HasValue && duration.Value > TimeSpan.FromHours(1))
                ? string.Format(Culture.InvariantCulture, ContentTimedJsonFormat, tokenScope, tokenUrl, Settings.MachineName, DateTime.UtcNow + duration.Value)
                : string.Format(Culture.InvariantCulture, ContentBasicJsonFormat, tokenScope, tokenUrl, Settings.MachineName);
            var content = new StringContent(jsonContent, Encoding.UTF8, HttpJsonContentType);

            return(content);
        }
Ejemplo n.º 2
0
 public MsaAuthentication(
     RuntimeContext context,
     TokenScope tokenScope,
     ICredentialStore personalAccessTokenStore)
     : base(context, tokenScope, personalAccessTokenStore)
 {
     Authority = new Authority(context, AzureDevOps.Authentication.Authority.DefaultAuthorityHostUrl);
 }
        /// <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);
        }
        /// <summary>
        /// Creates a new authentication broker based for the specified resource.
        /// <para/>
        /// Returns `<see langword="true"/>` if an authority could be determined; otherwise `<see langword="false"/>`.
        /// </summary>
        /// <param name="targetUri">The resource for which authentication is being requested.</param>
        /// <param name="scope">The scope of the access being requested.</param>
        /// <param name="personalAccessTokenStore">Storage container for personal access token secrets.</param>
        public static async Task <BaseAuthentication> GetAuthentication(
            RuntimeContext context,
            TargetUri targetUri,
            TokenScope scope,
            ICredentialStore personalAccessTokenStore)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }
            if (scope is null)
            {
                throw new ArgumentNullException(nameof(scope));
            }
            if (personalAccessTokenStore is null)
            {
                throw new ArgumentNullException(nameof(personalAccessTokenStore));
            }

            Guid?result = await DetectAuthority(context, targetUri);

            if (!result.HasValue)
            {
                return(null);
            }

            // Query for the tenant's identity
            Guid tenantId = result.Value;
            BaseAuthentication authentication = null;

            // empty identity is MSA, anything else is AAD
            if (tenantId == Guid.Empty)
            {
                context.Trace.WriteLine("MSA authority detected.");
                authentication = new MsaAuthentication(context, scope, personalAccessTokenStore);
            }
            else
            {
                context.Trace.WriteLine($"AAD authority for tenant '{tenantId.ToString("N")}' detected.");
                authentication = new AadAuthentication(context, tenantId, scope, personalAccessTokenStore);
                (authentication as AadAuthentication).TenantId = tenantId;
            }

            return(authentication);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Creates a new instance of `<see cref="AadAuthentication"/>`.
 /// </summary>
 /// <param name="tenantId">
 /// URI of the responsible Azure tenant.
 /// <para/>
 /// Use `<see cref="Authentication.GetAuthentication"/>` to detect the tenant identity and create the authentication object.
 /// </param>
 /// <param name="tokenScope">The scope of all access tokens acquired by the authority.</param>
 /// <param name="personalAccessTokenStore">The secure secret store for storing any personal access tokens acquired.</param>
 /// <param name="adaRefreshTokenStore">The secure secret store for storing any Azure tokens acquired.</param>
 public AadAuthentication(
     RuntimeContext context,
     Guid tenantId,
     TokenScope tokenScope,
     ICredentialStore personalAccessTokenStore)
     : base(context, tokenScope, personalAccessTokenStore)
 {
     if (tenantId == Guid.Empty)
     {
         Authority = new Authority(context, AzureDevOps.Authentication.Authority.DefaultAuthorityHostUrl);
     }
     else
     {
         // Create an authority host URL in the format of https://login.microsoft.com/12345678-9ABC-DEF0-1234-56789ABCDEF0.
         string authorityHost = AzureDevOps.Authentication.Authority.GetAuthorityUrl(tenantId);
         Authority = new Authority(context, authorityHost);
     }
 }
        protected Authentication(
            RuntimeContext context,
            TokenScope tokenScope,
            ICredentialStore personalAccessTokenStore)
            : base(context)
        {
            if (tokenScope is null)
            {
                throw new ArgumentNullException(nameof(tokenScope));
            }
            if (personalAccessTokenStore is null)
            {
                throw new ArgumentNullException(nameof(personalAccessTokenStore));
            }

            ClientId   = DefaultClientId;
            Resource   = DefaultResource;
            TokenScope = tokenScope;
            PersonalAccessTokenStore = personalAccessTokenStore;
            Authority = new Authority(context);
        }
Ejemplo n.º 7
0
        public static bool Find(string value, out TokenScope devopsScope)
        {
            devopsScope = EnumerateValues().FirstOrDefault(v => StringComparer.OrdinalIgnoreCase.Equals(v.Value, value));

            return(devopsScope != null);
        }
Ejemplo n.º 8
0
 public bool Equals(TokenScope other)
 => Microsoft.Alm.Authentication.TokenScope.Equals(this as Microsoft.Alm.Authentication.TokenScope, other as Microsoft.Alm.Authentication.TokenScope);
Ejemplo n.º 9
0
        public async Task <Token> GeneratePersonalAccessToken(TargetUri targetUri, Token authorization, TokenScope tokenScope, bool requireCompactToken, TimeSpan?tokenDuration)
        {
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }
            if (authorization is null)
            {
                throw new ArgumentNullException(nameof(authorization));
            }
            if (tokenScope is null)
            {
                throw new ArgumentNullException(nameof(tokenScope));
            }

            try
            {
                var requestUri = await CreatePersonalAccessTokenRequestUri(targetUri, authorization, requireCompactToken);

                var options = new NetworkRequestOptions(true)
                {
                    Authorization = authorization,
                };

                using (StringContent content = GetAccessTokenRequestBody(targetUri, tokenScope, tokenDuration))
                    using (var response = await Network.HttpPostAsync(requestUri, content, options))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            string responseText = response.Content.AsString;

                            if (!string.IsNullOrWhiteSpace(responseText))
                            {
                                // Find the 'token : <value>' portion of the result content, if any.
                                Match tokenMatch = null;
                                if ((tokenMatch = Regex.Match(responseText, @"\s*""token""\s*:\s*""([^\""]+)""\s*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)).Success)
                                {
                                    string tokenValue = tokenMatch.Groups[1].Value;
                                    Token  token      = new Token(tokenValue, TokenType.Personal);

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

                                    return(token);
                                }
                            }
                        }

                        Trace.WriteLine($"failed to acquire personal access token for '{targetUri}' [{(int)response.StatusCode}].");
                    }
            }
            catch (Exception exception)
            {
                Trace.WriteException(exception);
            }

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

            return(null);
        }
Ejemplo n.º 10
0
 public Task <Token> GeneratePersonalAccessToken(TargetUri targetUri, Token authorization, TokenScope tokenScope, bool requireCompactToken)
 => GeneratePersonalAccessToken(targetUri, authorization, tokenScope, requireCompactToken, null);