private IAccessToken GetManagedServiceToken(IAzureAccount account, IAzureEnvironment environment, string tenant, string resourceId)
        {
            if (environment == null)
            {
                throw new InvalidOperationException("Environment is required for MSI Login");
            }

            if (!account.IsPropertySet(AzureAccount.Property.MSILoginUri))
            {
                account.SetProperty(AzureAccount.Property.MSILoginUri, DefaultMSILoginUri);
            }

            if (!account.IsPropertySet(AzureAccount.Property.MSILoginUriBackup))
            {
                account.SetProperty(AzureAccount.Property.MSILoginUriBackup, DefaultBackupMSILoginUri);
            }

            if (string.IsNullOrWhiteSpace(tenant))
            {
                tenant = environment.AdTenant ?? "Common";
            }

            if (account.IsPropertySet(AuthenticationFactory.AppServiceManagedIdentityFlag))
            {
                return(new ManagedServiceAppServiceAccessToken(account, environment, tenant));
            }

            return(new ManagedServiceAccessToken(account, environment, GetResourceId(resourceId, environment), tenant));
        }
        /// <summary>
        /// Remove a user from token cache.
        /// </summary>
        /// <param name="account"></param>
        /// <param name="tokenCache">This parameter is no longer used. However to keep the API unchanged it's not removed.</param>
        public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache)
        {
            if (account != null && !string.IsNullOrEmpty(account.Id) && !string.IsNullOrWhiteSpace(account.Type))
            {
                switch (account.Type)
                {
                case AzureAccount.AccountType.AccessToken:
                    account.SetProperty(AzureAccount.Property.AccessToken, null);
                    account.SetProperty(AzureAccount.Property.GraphAccessToken, null);
                    account.SetProperty(AzureAccount.Property.KeyVaultAccessToken, null);
                    break;

                case AzureAccount.AccountType.ManagedService:
                    account.SetProperty(AzureAccount.Property.MSILoginUri, null);
                    break;

                case AzureAccount.AccountType.ServicePrincipal:
                    try
                    {
                        KeyStore.DeleteKey(account.Id, account.GetTenants().FirstOrDefault());
                    }
                    catch
                    {
                        // make best effort to remove credentials
                    }

                    RemoveFromTokenCache(account);
                    break;

                case AzureAccount.AccountType.User:
                    RemoveFromTokenCache(account);
                    break;
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="account"></param>
        /// <param name="environment"></param>
        /// <param name="tenant"></param>
        /// <param name="password"></param>
        /// <param name="promptBehavior"></param>
        /// <param name="promptAction"></param>
        /// <param name="tokenCache"></param>
        /// <param name="resourceId"></param>
        /// <returns></returns>
        public IAccessToken Authenticate(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenant,
            SecureString password,
            string promptBehavior,
            Action <string> promptAction,
            IAzureTokenCache tokenCache,
            string resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId)
        {
            IAccessToken token = null;

            PowerShellTokenCacheProvider tokenCacheProvider;

            if (!AzureSession.Instance.TryGetComponent(PowerShellTokenCacheProvider.PowerShellTokenCacheProviderKey, out tokenCacheProvider))
            {
                throw new NullReferenceException(Resources.AuthenticationClientFactoryNotRegistered);
            }

            Task <IAccessToken> authToken;
            var processAuthenticator = Builder.Authenticator;
            var retries = 5;

            while (retries-- > 0)
            {
                try
                {
                    while (processAuthenticator != null && processAuthenticator.TryAuthenticate(GetAuthenticationParameters(tokenCacheProvider, account, environment, tenant, password, promptBehavior, promptAction, tokenCache, resourceId), out authToken))
                    {
                        token = authToken?.ConfigureAwait(true).GetAwaiter().GetResult();
                        if (token != null)
                        {
                            // token.UserId is null when getting tenant token in ADFS environment
                            account.Id = token.UserId ?? account.Id;
                            if (!string.IsNullOrEmpty(token.HomeAccountId))
                            {
                                account.SetProperty(AzureAccount.Property.HomeAccountId, token.HomeAccountId);
                            }
                            break;
                        }

                        processAuthenticator = processAuthenticator.Next;
                    }
                }
                catch (Exception e)
                {
                    if (!IsTransientException(e) || retries == 0)
                    {
                        throw e;
                    }

                    TracingAdapter.Information(string.Format("[AuthenticationFactory] Exception caught when calling TryAuthenticate, retrying authentication - Exception message: '{0}'", e.Message));
                    continue;
                }

                break;
            }

            return(token);
        }
        public static List <AzureTenant> MergeTenants(this IAzureAccount account, IEnumerable <TenantIdDescription> tenants, IAccessToken token)
        {
            List <AzureTenant> result = null;

            if (tenants != null)
            {
                var existingTenants = new List <AzureTenant>();
                account.SetProperty(AzureAccount.Property.Tenants, null);
                tenants.ForEach((t) =>
                {
                    existingTenants.Add(new AzureTenant {
                        Id = t.TenantId, Directory = token.GetDomain()
                    });
                    account.SetOrAppendProperty(AzureAccount.Property.Tenants, t.TenantId);
                });

                result = existingTenants;
            }

            return(result);
        }
Ejemplo n.º 5
0
        public AzureRmProfile Login(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenantId,
            string subscriptionId,
            string subscriptionName,
            SecureString password,
            bool skipValidation,
            Action <string> promptAction,
            string name = null)
        {
            IAzureSubscription newSubscription = null;
            IAzureTenant       newTenant       = null;
            string             promptBehavior  =
                (password == null &&
                 account.Type != AzureAccount.AccountType.AccessToken &&
                 account.Type != AzureAccount.AccountType.ManagedService &&
                 !account.IsPropertySet(AzureAccount.Property.CertificateThumbprint))
                ? ShowDialog.Always : ShowDialog.Never;

            if (skipValidation)
            {
                if (string.IsNullOrEmpty(subscriptionId) || string.IsNullOrEmpty(tenantId))
                {
                    throw new PSInvalidOperationException(Resources.SubscriptionOrTenantMissing);
                }

                newSubscription = new AzureSubscription
                {
                    Id = subscriptionId
                };

                newSubscription.SetOrAppendProperty(AzureSubscription.Property.Tenants, tenantId);
                newSubscription.SetOrAppendProperty(AzureSubscription.Property.Account, account.Id);

                newTenant = new AzureTenant
                {
                    Id = tenantId
                };
            }

            else
            {
                // (tenant and subscription are present) OR
                // (tenant is present and subscription is not provided)
                if (!string.IsNullOrEmpty(tenantId))
                {
                    var token = AcquireAccessToken(
                        account,
                        environment,
                        tenantId,
                        password,
                        promptBehavior,
                        promptAction);
                    if (TryGetTenantSubscription(
                            token,
                            account,
                            environment,
                            tenantId,
                            subscriptionId,
                            subscriptionName,
                            out newSubscription,
                            out newTenant))
                    {
                        account.SetOrAppendProperty(AzureAccount.Property.Tenants, new[] { newTenant.Id.ToString() });
                    }
                }
                // (tenant is not provided and subscription is present) OR
                // (tenant is not provided and subscription is not provided)
                else
                {
                    var tenants = ListAccountTenants(account, environment, password, promptBehavior, promptAction)
                                  .Select(s => s.Id.ToString()).ToList();
                    account.SetProperty(AzureAccount.Property.Tenants, null);
                    string accountId = null;

                    foreach (var tenant in tenants)
                    {
                        IAzureTenant       tempTenant;
                        IAzureSubscription tempSubscription;

                        IAccessToken token = null;

                        try
                        {
                            token = AcquireAccessToken(account, environment, tenant, password, ShowDialog.Auto, null);
                            if (accountId == null)
                            {
                                accountId = account.Id;
                                account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                            }
                            else if (accountId.Equals(account.Id, StringComparison.OrdinalIgnoreCase))
                            {
                                account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                            }
                            else
                            {   // if account ID is different from the first tenant account id we need to ignore current tenant
                                WriteWarningMessage(string.Format(
                                                        ProfileMessages.AccountIdMismatch,
                                                        account.Id,
                                                        tenant,
                                                        accountId));
                                account.Id = accountId;
                                token      = null;
                            }
                        }
                        catch
                        {
                            WriteWarningMessage(string.Format(ProfileMessages.UnableToAqcuireToken, tenant));
                        }

                        if (token != null &&
                            newTenant == null &&
                            TryGetTenantSubscription(token, account, environment, tenant, subscriptionId, subscriptionName, out tempSubscription, out tempTenant))
                        {
                            // If no subscription found for the given token/tenant
                            // discard tempTenant value unless current token/tenant is the last one.
                            if (tempSubscription != null || tenant.Equals(tenants[tenants.Count - 1]))
                            {
                                newTenant       = tempTenant;
                                newSubscription = tempSubscription;
                            }
                        }
                    }
                }
            }

            if (newSubscription == null)
            {
                if (subscriptionId != null)
                {
                    throw new PSInvalidOperationException(String.Format(ResourceMessages.SubscriptionIdNotFound, account.Id, subscriptionId));
                }
                else if (subscriptionName != null)
                {
                    throw new PSInvalidOperationException(String.Format(ResourceMessages.SubscriptionNameNotFound, account.Id, subscriptionName));
                }

                var newContext = new AzureContext(account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(name, newContext))
                {
                    WriteWarningMessage(string.Format(ProfileMessages.CannotSetDefaultContext, newContext.ToString()));
                }
            }
            else
            {
                var newContext = new AzureContext(newSubscription, account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(name, newContext))
                {
                    WriteWarningMessage(string.Format(ProfileMessages.CannotSetDefaultContext, newContext.ToString()));
                }

                if (!skipValidation && !newSubscription.State.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
                {
                    WriteWarningMessage(string.Format(
                                            ProfileMessages.SelectedSubscriptionNotActive,
                                            newSubscription.State));
                }
            }

            _profile.DefaultContext.TokenCache = _cache;

            return(_profile.ToProfile());
        }
Ejemplo n.º 6
0
        private bool TryGetTenantSubscription(IAccessToken accessToken,
                                              IAzureAccount account,
                                              IAzureEnvironment environment,
                                              string subscriptionId,
                                              string subscriptionName,
                                              bool isTenantPresent,
                                              out IAzureSubscription subscription,
                                              out IAzureTenant tenant)
        {
            subscription = null;
            if (accessToken != null)
            {
                try
                {
                    if (!string.IsNullOrEmpty(subscriptionId))
                    {
                        subscription = SubscriptionAndTenantClient?.GetSubscriptionById(subscriptionId, accessToken, new AzureAccount {
                            Id = accessToken.UserId
                        }, environment);
                    }
                    else
                    {
                        var subscriptions = SubscriptionAndTenantClient?.ListAllSubscriptionsForTenant(accessToken, new AzureAccount {
                            Id = accessToken.UserId
                        }, environment)?.ToList()
                                            .Where(s => "enabled".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase) || "warned".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase));

                        account.SetProperty(AzureAccount.Property.Subscriptions, subscriptions.Select(i => i.GetId().ToString()).ToArray());

                        if (subscriptions.Any())
                        {
                            if (!string.IsNullOrEmpty(subscriptionName))
                            {
                                subscription = subscriptions.FirstOrDefault(
                                    s => s.Name.Equals(subscriptionName, StringComparison.OrdinalIgnoreCase));
                            }
                            else
                            {
                                if (subscriptions.Count() > 1)
                                {
                                    WriteWarningMessage(string.Format(
                                                            "TenantId '{0}' contains more than one active subscription. First one will be selected for further use. " +
                                                            "To select another subscription, use Set-AzContext.",
                                                            accessToken.TenantId));
                                }
                                subscription = subscription ?? subscriptions.First();
                            }
                        }
                    }
                }
                catch (CloudException ex)
                {
                    //Error "InvalidAuthenticationTokenTenant" means tenant and subscription mismatches.
                    //If tenant is not present, we're iterating all tenants until finding right tenant for specified subscription,
                    //in this case, InvalidAuthenticationTokenTenant message is expected and we should ignore it.
                    if (isTenantPresent || !string.Equals(ex.Body?.Code, "InvalidAuthenticationTokenTenant", StringComparison.OrdinalIgnoreCase))
                    {
                        WriteWarningMessage(ex.Message);
                    }
                }

                if (subscription != null)
                {
                    subscription.SetAccount(accessToken.UserId);
                    subscription.SetEnvironment(environment.Name);
                    subscription.SetTenant(accessToken.TenantId);

                    tenant    = new AzureTenant();
                    tenant.Id = accessToken.TenantId;
                    return(true);
                }

                subscription = null;

                if (accessToken != null && accessToken.TenantId != null)
                {
                    tenant    = new AzureTenant();
                    tenant.Id = accessToken.TenantId;
                    return(true);
                }
            }
            tenant = null;
            return(false);
        }
Ejemplo n.º 7
0
        public AzureRmProfile Login(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenantId,
            string subscriptionId,
            string subscriptionName,
            SecureString password,
            bool skipValidation,
            Action <string> promptAction,
            string name = null,
            bool shouldPopulateContextList = true,
            int maxContextPopulation       = Profile.ConnectAzureRmAccountCommand.DefaultMaxContextPopulation)
        {
            IAzureSubscription newSubscription = null;
            IAzureTenant       newTenant       = null;
            string             promptBehavior  =
                (password == null &&
                 account.Type != AzureAccount.AccountType.AccessToken &&
                 account.Type != AzureAccount.AccountType.ManagedService &&
                 !account.IsPropertySet(AzureAccount.Property.CertificateThumbprint))
                ? ShowDialog.Always : ShowDialog.Never;

            SubscritpionClientCandidates.Reset();

            if (skipValidation)
            {
                if (string.IsNullOrEmpty(subscriptionId) || string.IsNullOrEmpty(tenantId))
                {
                    throw new PSInvalidOperationException(Resources.SubscriptionOrTenantMissing);
                }

                newSubscription = new AzureSubscription
                {
                    Id = subscriptionId
                };

                newSubscription.SetOrAppendProperty(AzureSubscription.Property.Tenants, tenantId);
                newSubscription.SetOrAppendProperty(AzureSubscription.Property.Account, account.Id);

                newTenant = new AzureTenant
                {
                    Id = tenantId
                };
            }
            else
            {
                // (tenant and subscription are present) OR
                // (tenant is present and subscription is not provided)
                if (!string.IsNullOrEmpty(tenantId))
                {
                    Guid tempGuid = Guid.Empty;
                    if (!Guid.TryParse(tenantId, out tempGuid))
                    {
                        var tenants     = ListAccountTenants(account, environment, password, promptBehavior, promptAction);
                        var homeTenants = tenants.FirstOrDefault(t => t.IsHome);
                        var tenant      = homeTenants ?? tenants.FirstOrDefault();
                        if (tenant == null || tenant.Id == null)
                        {
                            string baseMessage    = string.Format(ProfileMessages.TenantDomainNotFound, tenantId);
                            var    typeMessageMap = new Dictionary <string, string>
                            {
                                { AzureAccount.AccountType.ServicePrincipal, string.Format(ProfileMessages.ServicePrincipalTenantDomainNotFound, account.Id) },
                                { AzureAccount.AccountType.User, ProfileMessages.UserTenantDomainNotFound },
                                { AzureAccount.AccountType.ManagedService, ProfileMessages.MSITenantDomainNotFound }
                            };
                            string typeMessage = typeMessageMap.ContainsKey(account.Type) ? typeMessageMap[account.Type] : string.Empty;
                            throw new ArgumentNullException(string.Format("{0} {1}", baseMessage, typeMessage));
                        }

                        tenantId = tenant.Id;
                    }


                    var token = AcquireAccessToken(
                        account,
                        environment,
                        tenantId,
                        password,
                        promptBehavior,
                        promptAction);
                    if (TryGetTenantSubscription(
                            token,
                            account,
                            environment,
                            subscriptionId,
                            subscriptionName,
                            true,
                            out newSubscription,
                            out newTenant))
                    {
                        account.SetOrAppendProperty(AzureAccount.Property.Tenants, new[] { newTenant.Id.ToString() });
                    }
                }
                // (tenant is not provided and subscription is present) OR
                // (tenant is not provided and subscription is not provided)
                else
                {
                    var tenants = ListAccountTenants(account, environment, password, promptBehavior, promptAction)
                                  .Select(s => s.Id.ToString()).ToList();
                    account.SetProperty(AzureAccount.Property.Tenants, null);
                    string             accountId        = null;
                    IAzureTenant       tempTenant       = null;
                    IAzureSubscription tempSubscription = null;
                    foreach (var tenant in tenants)
                    {
                        tempTenant       = null;
                        tempSubscription = null;

                        IAccessToken token = null;

                        try
                        {
                            token = AcquireAccessToken(account, environment, tenant, password, ShowDialog.Auto, null);
                            if (accountId == null)
                            {
                                accountId = account.Id;
                                account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                            }
                            else if (accountId.Equals(account.Id, StringComparison.OrdinalIgnoreCase))
                            {
                                account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                            }
                            else
                            {   // if account ID is different from the first tenant account id we need to ignore current tenant
                                WriteWarningMessage(string.Format(
                                                        ProfileMessages.AccountIdMismatch,
                                                        account.Id,
                                                        tenant,
                                                        accountId));
                                account.Id = accountId;
                                token      = null;
                            }
                        }
                        catch
                        {
                            WriteWarningMessage(string.Format(ProfileMessages.UnableToAqcuireToken, tenant));
                        }

                        if (token != null &&
                            newTenant == null &&
                            TryGetTenantSubscription(token, account, environment, subscriptionId, subscriptionName, false, out tempSubscription, out tempTenant))
                        {
                            // If no subscription found for the given token/tenant,discard tempTenant value.
                            // Continue to look for matched subscripitons until one subscription retrived by its home tenant is found.
                            if (tempSubscription != null)
                            {
                                newSubscription = tempSubscription;
                                if (tempSubscription.GetTenant() == tempSubscription.GetHomeTenant())
                                {
                                    newTenant = tempTenant;
                                }
                            }
                        }
                    }
                    newSubscription = newSubscription ?? tempSubscription;
                    newTenant       = newTenant ??
                                      (newSubscription != null ? new AzureTenant()
                    {
                        Id = newSubscription.GetTenant()
                    } : tempTenant);
                }
            }

            shouldPopulateContextList &= _profile.DefaultContext?.Account == null;
            if (newSubscription == null)
            {
                if (subscriptionId != null)
                {
                    throw new PSInvalidOperationException(String.Format(ResourceMessages.SubscriptionIdNotFound, account.Id, subscriptionId));
                }
                else if (subscriptionName != null)
                {
                    throw new PSInvalidOperationException(String.Format(ResourceMessages.SubscriptionNameNotFound, account.Id, subscriptionName));
                }

                var newContext = new AzureContext(account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(name, newContext))
                {
                    WriteWarningMessage(string.Format(ProfileMessages.CannotSetDefaultContext, newContext.ToString()));
                }
            }
            else
            {
                var newContext = new AzureContext(newSubscription, account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(name, newContext))
                {
                    WriteWarningMessage(string.Format(ProfileMessages.CannotSetDefaultContext, newContext.ToString()));
                }

                if (!skipValidation && !newSubscription.State.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
                {
                    WriteWarningMessage(string.Format(
                                            ProfileMessages.SelectedSubscriptionNotActive,
                                            newSubscription.State));
                }
            }

            _profile.DefaultContext.TokenCache = _cache;
            if (shouldPopulateContextList && maxContextPopulation != 0)
            {
                var defaultContext = _profile.DefaultContext;
                var subscriptions  = maxContextPopulation > 0 ? ListSubscriptions(tenantId).Take(maxContextPopulation) : ListSubscriptions(tenantId);

                foreach (var subscription in subscriptions)
                {
                    IAzureTenant tempTenant = new AzureTenant()
                    {
                        Id = subscription.GetProperty(AzureSubscription.Property.Tenants)
                    };

                    var tempContext = new AzureContext(subscription, account, environment, tempTenant);
                    tempContext.TokenCache = _cache;
                    string tempName = null;
                    if (!_profile.TryGetContextName(tempContext, out tempName))
                    {
                        WriteWarningMessage(string.Format(Resources.CannotGetContextName, subscription.Id));
                        continue;
                    }

                    if (!_profile.TrySetContext(tempName, tempContext))
                    {
                        WriteWarningMessage(string.Format(Resources.CannotCreateContext, subscription.Id));
                    }
                }

                _profile.TrySetDefaultContext(defaultContext);
                _profile.TryRemoveContext("Default");
            }

            return(_profile.ToProfile());
        }
 /// <summary>
 /// Set the subscriptiosn associated with the account
 /// </summary>
 /// <param name="account">The account to change</param>
 /// <param name="subscriptions">The subscriptions to add to the account</param>
 public static void SetSubscriptions(this IAzureAccount account, params string[] subscriptions)
 {
     account.SetProperty(AzureAccount.Property.Subscriptions, subscriptions);
 }
 /// <summary>
 /// Set the certificate thumbprint for the account
 /// </summary>
 /// <param name="account">The account to change</param>
 /// <param name="thumbprint">The thumbprint of the accoutn credential certificate</param>
 public static void SetThumbprint(this IAzureAccount account, string thumbprint)
 {
     account.SetProperty(AzureAccount.Property.CertificateThumbprint, thumbprint);
 }
 /// <summary>
 /// Set the access token for the account
 /// </summary>
 /// <param name="account">The account to change</param>
 /// <param name="token">The account access token</param>
 public static void SetAccessToken(this IAzureAccount account, string token)
 {
     account.SetProperty(AzureAccount.Property.AccessToken, token);
 }
Ejemplo n.º 11
0
        private bool TryGetTenantSubscription(IAccessToken accessToken,
                                              IAzureAccount account,
                                              IAzureEnvironment environment,
                                              string subscriptionId,
                                              string subscriptionName,
                                              out IAzureSubscription subscription,
                                              out IAzureTenant tenant)
        {
            subscription = null;
            if (accessToken != null)
            {
                try
                {
                    if (!string.IsNullOrEmpty(subscriptionId))
                    {
                        subscription = SubscriptionAndTenantClient?.GetSubscriptionById(subscriptionId, accessToken, new AzureAccount {
                            Id = accessToken.UserId
                        }, environment);
                    }
                    else
                    {
                        var subscriptions = SubscriptionAndTenantClient?.ListAllSubscriptionsForTenant(accessToken, new AzureAccount {
                            Id = accessToken.UserId
                        }, environment)?.ToList()
                                            .Where(s => "enabled".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase) || "warned".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase));

                        account.SetProperty(AzureAccount.Property.Subscriptions, subscriptions.Select(i => i.GetId().ToString()).ToArray());

                        if (subscriptions.Any())
                        {
                            if (!string.IsNullOrEmpty(subscriptionName))
                            {
                                subscription = subscriptions.FirstOrDefault(
                                    s => s.Name.Equals(subscriptionName, StringComparison.OrdinalIgnoreCase));
                            }
                            else
                            {
                                if (subscriptions.Count() > 1)
                                {
                                    WriteWarningMessage(string.Format(
                                                            "TenantId '{0}' contains more than one active subscription. First one will be selected for further use. " +
                                                            "To select another subscription, use Set-AzContext.",
                                                            accessToken.TenantId));
                                }
                                subscription = subscription ?? subscriptions.First();
                            }
                        }
                    }
                }
                catch (CloudException ex)
                {
                    WriteWarningMessage(ex.Message);
                }

                if (subscription != null)
                {
                    subscription.SetAccount(accessToken.UserId);
                    subscription.SetEnvironment(environment.Name);
                    subscription.SetTenant(accessToken.TenantId);

                    tenant    = new AzureTenant();
                    tenant.Id = accessToken.TenantId;
                    return(true);
                }

                subscription = null;

                if (accessToken != null && accessToken.TenantId != null)
                {
                    tenant    = new AzureTenant();
                    tenant.Id = accessToken.TenantId;
                    return(true);
                }
            }
            tenant = null;
            return(false);
        }
Ejemplo n.º 12
0
        public AzureRmProfile Login(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenantId,
            string subscriptionId,
            string subscriptionName,
            SecureString password)
        {
            IAzureSubscription newSubscription = null;
            IAzureTenant       newTenant       = null;
            string             promptBehavior  =
                (password == null &&
                 account.Type != AzureAccount.AccountType.AccessToken &&
                 !account.IsPropertySet(AzureAccount.Property.CertificateThumbprint))
                ? ShowDialog.Always : ShowDialog.Never;

            // (tenant and subscription are present) OR
            // (tenant is present and subscription is not provided)
            if (!string.IsNullOrEmpty(tenantId))
            {
                var token = AcquireAccessToken(account, environment, tenantId, password, promptBehavior);
                if (TryGetTenantSubscription(token, account, environment, tenantId, subscriptionId, subscriptionName, out newSubscription, out newTenant))
                {
                    account.SetOrAppendProperty(AzureAccount.Property.Tenants, new[] { newTenant.Id.ToString() });
                }
            }
            // (tenant is not provided and subscription is present) OR
            // (tenant is not provided and subscription is not provided)
            else
            {
                var tenants = ListAccountTenants(account, environment, password, promptBehavior).Select(s => s.Id.ToString()).ToArray();
                account.SetProperty(AzureAccount.Property.Tenants, null);
                string accountId = null;

                for (int i = 0; i < tenants.Count(); i++)
                {
                    var tenant = tenants[i];

                    IAzureTenant       tempTenant;
                    IAzureSubscription tempSubscription;

                    IAccessToken token = null;

                    try
                    {
                        token = AcquireAccessToken(account, environment, tenant, password, ShowDialog.Auto);

                        if (accountId == null)
                        {
                            accountId = account.Id;
                            account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                        }
                        else if (accountId.Equals(account.Id, StringComparison.OrdinalIgnoreCase))
                        {
                            account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                        }
                        else
                        {   // if account ID is different from the first tenant account id we need to ignore current tenant
                            WriteWarningMessage(string.Format(
                                                    Microsoft.Azure.Commands.Profile.Properties.Resources.AccountIdMismatch,
                                                    account.Id,
                                                    tenant,
                                                    accountId));
                            account.Id = accountId;
                            token      = null;
                        }
                    }
                    catch
                    {
                        WriteWarningMessage(string.Format(Microsoft.Azure.Commands.Profile.Properties.Resources.UnableToAqcuireToken, tenant));
                    }

                    if (token != null &&
                        newTenant == null &&
                        TryGetTenantSubscription(token, account, environment, tenant, subscriptionId, subscriptionName, out tempSubscription, out tempTenant))
                    {
                        // If no subscription found for the given token/tenant
                        // discard tempTenant value unless current token/tenant is the last one.
                        if (tempSubscription != null || i == (tenants.Count() - 1))
                        {
                            newTenant       = tempTenant;
                            newSubscription = tempSubscription;
                        }
                    }
                }
            }

            if (newSubscription == null)
            {
                if (subscriptionId != null)
                {
                    throw new PSInvalidOperationException(String.Format(Properties.Resources.SubscriptionIdNotFound, account.Id, subscriptionId));
                }
                else if (subscriptionName != null)
                {
                    throw new PSInvalidOperationException(String.Format(Properties.Resources.SubscriptionNameNotFound, account.Id, subscriptionName));
                }

                _profile.DefaultContext = new AzureContext(account, environment, newTenant);
            }
            else
            {
                _profile.DefaultContext = new AzureContext(newSubscription, account, environment, newTenant);
                if (!newSubscription.State.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
                {
                    WriteWarningMessage(string.Format(
                                            Microsoft.Azure.Commands.Profile.Properties.Resources.SelectedSubscriptionNotActive,
                                            newSubscription.State));
                }
            }

            _profile.DefaultContext.TokenCache = _cache;

            return(_profile);
        }
Ejemplo n.º 13
0
        private bool TryGetTenantSubscription(IAccessToken accessToken,
                                              IAzureAccount account,
                                              IAzureEnvironment environment,
                                              string tenantId,
                                              string subscriptionId,
                                              string subscriptionName,
                                              out IAzureSubscription subscription,
                                              out IAzureTenant tenant)
        {
            using (var subscriptionClient = AzureSession.Instance.ClientFactory.CreateCustomArmClient <SubscriptionClient>(
                       environment.GetEndpointAsUri(AzureEnvironment.Endpoint.ResourceManager),
                       new TokenCredentials(accessToken.AccessToken) as ServiceClientCredentials,
                       AzureSession.Instance.ClientFactory.GetCustomHandlers()))
            {
                Subscription subscriptionFromServer = null;

                try
                {
                    if (subscriptionId != null)
                    {
                        subscriptionFromServer = subscriptionClient.Subscriptions.Get(subscriptionId);
                    }
                    else
                    {
                        var subscriptions = (subscriptionClient.ListAllSubscriptions().ToList() ??
                                             new List <Subscription>())
                                            .Where(s => "enabled".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase) ||
                                                   "warned".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase));

                        account.SetProperty(AzureAccount.Property.Subscriptions, subscriptions.Select(i => i.SubscriptionId).ToArray());

                        if (subscriptions.Any())
                        {
                            if (subscriptionName != null)
                            {
                                subscriptionFromServer = subscriptions.FirstOrDefault(
                                    s => s.DisplayName.Equals(subscriptionName, StringComparison.OrdinalIgnoreCase));
                            }
                            else
                            {
                                if (subscriptions.Count() > 1)
                                {
                                    // TenantId contains more than one active subscription. First one will be selected for further use.
                                }
                                subscriptionFromServer = subscriptions.First();
                            }
                        }
                    }
                }
                catch (CloudException ex)
                {
                    // Warning
                    if (ex != null)
                    {
                    }
                }

                if (subscriptionFromServer != null)
                {
                    subscription = new AzureSubscription
                    {
                        Id    = subscriptionFromServer.SubscriptionId,
                        Name  = subscriptionFromServer.DisplayName,
                        State = subscriptionFromServer.State.ToString()
                    };

                    subscription.SetAccount(accessToken.UserId);
                    subscription.SetEnvironment(environment.Name);
                    subscription.SetTenant(accessToken.TenantId);

                    tenant    = new AzureTenant();
                    tenant.Id = accessToken.TenantId;
                    return(true);
                }

                subscription = null;

                if (accessToken != null && accessToken.TenantId != null)
                {
                    tenant    = new AzureTenant();
                    tenant.Id = accessToken.TenantId;
                    return(true);
                }

                tenant = null;
                return(false);
            }
        }
Ejemplo n.º 14
0
        private void Login(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenantId,
            string subscriptionId,
            string subscriptionName,
            SecureString password,
            Action <string> promptAction)
        {
            IAzureSubscription newSubscription = null;
            IAzureTenant       newTenant       = null;
            string             promptBehavior  =
                (password == null &&
                 account.Type != AzureAccount.AccountType.AccessToken &&
                 account.Type != AzureAccount.AccountType.ManagedService &&
                 !account.IsPropertySet(AzureAccount.Property.CertificateThumbprint))
                ? ShowDialog.Always : ShowDialog.Never;

            // (tenant and subscription are present) OR
            // (tenant is present and subscription is not provided)
            if (!string.IsNullOrEmpty(tenantId))
            {
                Guid tempGuid = Guid.Empty;
                if (!Guid.TryParse(tenantId, out tempGuid))
                {
                    var tenant = ListAccountTenants(
                        account,
                        environment,
                        password,
                        promptBehavior,
                        promptAction)?.FirstOrDefault();
                    if (tenant == null || tenant.Id == null)
                    {
                        throw new ArgumentNullException(string.Format("Could not find tenant id for provided tenant domain '{0}'. Please ensure that " +
                                                                      "the provided service principal is found in the provided tenant domain.", tenantId));
                    }

                    tenantId = tenant.Id;
                }

                var token = AcquireAccessToken(
                    account,
                    environment,
                    tenantId,
                    password,
                    promptBehavior,
                    promptAction);
                if (TryGetTenantSubscription(
                        token,
                        account,
                        environment,
                        tenantId,
                        subscriptionId,
                        subscriptionName,
                        out newSubscription,
                        out newTenant))
                {
                    account.SetOrAppendProperty(AzureAccount.Property.Tenants, new[] { newTenant.Id.ToString() });
                }
            }
            // (tenant is not provided and subscription is present) OR
            // (tenant is not provided and subscription is not provided)
            else
            {
                var tenants = ListAccountTenants(account, environment, password, promptBehavior, promptAction)
                              .Select(s => s.Id.ToString()).ToList();
                account.SetProperty(AzureAccount.Property.Tenants, null);
                string accountId = null;

                foreach (var tenant in tenants)
                {
                    IAzureTenant       tempTenant;
                    IAzureSubscription tempSubscription;

                    IAccessToken token = null;

                    try
                    {
                        token = AcquireAccessToken(account, environment, tenant, password, ShowDialog.Auto, null);
                        if (accountId == null)
                        {
                            accountId = account.Id;
                            account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                        }
                        else if (accountId.Equals(account.Id, StringComparison.OrdinalIgnoreCase))
                        {
                            account.SetOrAppendProperty(AzureAccount.Property.Tenants, tenant);
                        }
                        else
                        {   // if account ID is different from the first tenant account id we need to ignore current tenant
                            account.Id = accountId;
                            token      = null;
                        }
                    }
                    catch
                    {
                        // Unable to acquire token for tenant
                    }

                    if (token != null &&
                        newTenant == null &&
                        TryGetTenantSubscription(token, account, environment, tenant, subscriptionId, subscriptionName, out tempSubscription, out tempTenant))
                    {
                        // If no subscription found for the given token/tenant
                        // discard tempTenant value unless current token/tenant is the last one.
                        if (tempSubscription != null || tenant.Equals(tenants[tenants.Count - 1]))
                        {
                            newTenant       = tempTenant;
                            newSubscription = tempSubscription;
                        }
                    }
                }
            }

            if (newSubscription == null)
            {
                if (subscriptionId != null)
                {
                    throw new PSInvalidOperationException(String.Format("The provided account {0} does not have access to subscription ID '{1}'. Please try logging in with different credentials or a different subscription ID.", account.Id, subscriptionId));
                }
                else if (subscriptionName != null)
                {
                    throw new PSInvalidOperationException(String.Format("The provided account {0} does not have access to subscription name '{1}'. Please try logging in with different credentials or a different subscription name.", account.Id, subscriptionName));
                }

                var newContext = new AzureContext(account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(null, newContext))
                {
                    // Unable to set default context
                }
            }
            else
            {
                var newContext = new AzureContext(newSubscription, account, environment, newTenant);
                if (!_profile.TrySetDefaultContext(null, newContext))
                {
                    // Unable to set default context
                }

                if (!newSubscription.State.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
                {
                    // Selected subscription is not in an "enabled" state
                }
            }

            _profile.DefaultContext.TokenCache = _cache;
            var defaultContext = _profile.DefaultContext;
            var subscriptions  = ListSubscriptions(tenantId).Take(25);

            foreach (var subscription in subscriptions)
            {
                IAzureTenant tempTenant = new AzureTenant()
                {
                    Id = subscription.GetTenant()
                };

                var tempContext = new AzureContext(subscription, account, environment, tempTenant);
                tempContext.TokenCache = _cache;
                string tempName = null;
                if (!_profile.TryGetContextName(tempContext, out tempName))
                {
                    // Unable to get context name for subscription
                    continue;
                }

                if (!_profile.TrySetContext(tempName, tempContext))
                {
                    // Cannot create a context for subscription
                }

                _profile.TrySetDefaultContext(defaultContext);
                _profile.TryRemoveContext("Default");
            }

            _profile.Dispose();
        }
Ejemplo n.º 15
0
        private bool TryGetTenantSubscription(IAccessToken accessToken,
                                              IAzureAccount account,
                                              IAzureEnvironment environment,
                                              string tenantId,
                                              string subscriptionId,
                                              string subscriptionName,
                                              out IAzureSubscription subscription,
                                              out IAzureTenant tenant)
        {
            using (var subscriptionClient = AzureSession.Instance.ClientFactory.CreateCustomArmClient <SubscriptionClient>(
                       environment.GetEndpointAsUri(AzureEnvironment.Endpoint.ResourceManager),
                       new TokenCredentials(accessToken.AccessToken) as ServiceClientCredentials,
                       AzureSession.Instance.ClientFactory.GetCustomHandlers()))
            {
                Subscription subscriptionFromServer = null;

                try
                {
                    if (subscriptionId != null)
                    {
                        subscriptionFromServer = subscriptionClient.Subscriptions.Get(subscriptionId);
                    }
                    else
                    {
                        var subscriptions = (subscriptionClient.ListAll().ToList() ??
                                             new List <Subscription>())
                                            .Where(s => "enabled".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase) ||
                                                   "warned".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase));

                        account.SetProperty(AzureAccount.Property.Subscriptions, subscriptions.Select(i => i.SubscriptionId).ToArray());

                        if (subscriptions.Any())
                        {
                            if (subscriptionName != null)
                            {
                                subscriptionFromServer = subscriptions.FirstOrDefault(
                                    s => s.DisplayName.Equals(subscriptionName, StringComparison.OrdinalIgnoreCase));
                            }
                            else
                            {
                                if (subscriptions.Count() > 1)
                                {
                                    WriteWarningMessage(string.Format(
                                                            "TenantId '{0}' contains more than one active subscription. First one will be selected for further use. " +
                                                            "To select another subscription, use Set-AzureRmContext.",
                                                            tenantId));
                                }
                                subscriptionFromServer = subscriptions.First();
                            }
                        }
                    }
                }
                catch (CloudException ex)
                {
                    WriteWarningMessage(ex.Message);
                }

                if (subscriptionFromServer != null)
                {
                    subscription = new AzureSubscription
                    {
                        Id    = subscriptionFromServer.SubscriptionId,
                        Name  = subscriptionFromServer.DisplayName,
                        State = subscriptionFromServer.State.ToString()
                    };

                    subscription.SetAccount(accessToken.UserId);
                    subscription.SetEnvironment(environment.Name);
                    subscription.SetTenant(accessToken.TenantId);

                    tenant           = new AzureTenant();
                    tenant.Id        = accessToken.TenantId;
                    tenant.Directory = accessToken.GetDomain();
                    return(true);
                }

                subscription = null;

                if (accessToken != null && accessToken.TenantId != null)
                {
                    tenant    = new AzureTenant();
                    tenant.Id = accessToken.TenantId;
                    if (accessToken.UserId != null)
                    {
                        var domain = accessToken.UserId.Split(new[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
                        if (domain.Length == 2)
                        {
                            tenant.Directory = domain[1];
                        }
                    }
                    return(true);
                }

                tenant = null;
                return(false);
            }
        }
 /// <summary>
 /// Set the tenants the accoutn has access to
 /// </summary>
 /// <param name="account">The account to change</param>
 /// <param name="tenants">The set of tenants the account has access to</param>
 public static void SetTenants(this IAzureAccount account, params string[] tenants)
 {
     account.SetProperty(AzureAccount.Property.Tenants, tenants);
 }
Ejemplo n.º 17
0
        public IAccessToken Authenticate(
            IAzureAccount account,
            IAzureEnvironment environment,
            string tenant,
            SecureString password,
            string promptBehavior,
            Action <string> promptAction,
            IAzureTokenCache tokenCache,
            string resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId)
        {
            IAccessToken token;
            var          cache = tokenCache as TokenCache;

            if (cache == null)
            {
                cache = TokenCache.DefaultShared;
            }

            var configuration = GetAdalConfiguration(environment, tenant, resourceId, cache);

            TracingAdapter.Information(
                Resources.AdalAuthConfigurationTrace,
                configuration.AdDomain,
                configuration.AdEndpoint,
                configuration.ClientId,
                configuration.ClientRedirectUri,
                configuration.ResourceClientUri,
                configuration.ValidateAuthority);
            if (account != null && account.Type == AzureAccount.AccountType.ManagedService)
            {
                if (environment == null)
                {
                    throw new InvalidOperationException("Environment is required for MSI Login");
                }

                if (!account.IsPropertySet(AzureAccount.Property.MSILoginUri))
                {
                    account.SetProperty(AzureAccount.Property.MSILoginUri, DefaultMSILoginUri);
                }

                if (string.IsNullOrWhiteSpace(tenant))
                {
                    tenant = environment.AdTenant ?? "Common";
                }

                token = new ManagedServiceAccessToken(account, environment, GetResourceId(resourceId, environment), tenant);
            }
            else if (account != null && environment != null &&
                     account.Type == AzureAccount.AccountType.AccessToken)
            {
                var rawToken = new RawAccessToken
                {
                    TenantId  = tenant,
                    UserId    = account.Id,
                    LoginType = AzureAccount.AccountType.AccessToken
                };

                if ((string.Equals(resourceId, environment.AzureKeyVaultServiceEndpointResourceId, StringComparison.OrdinalIgnoreCase) ||
                     string.Equals(AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId, resourceId, StringComparison.OrdinalIgnoreCase)) &&
                    account.IsPropertySet(AzureAccount.Property.KeyVaultAccessToken))
                {
                    rawToken.AccessToken = account.GetProperty(AzureAccount.Property.KeyVaultAccessToken);
                }
                else if ((string.Equals(resourceId, environment.GraphEndpointResourceId, StringComparison.OrdinalIgnoreCase) ||
                          string.Equals(AzureEnvironment.Endpoint.GraphEndpointResourceId, resourceId, StringComparison.OrdinalIgnoreCase)) &&
                         account.IsPropertySet(AzureAccount.Property.GraphAccessToken))
                {
                    rawToken.AccessToken = account.GetProperty(AzureAccount.Property.GraphAccessToken);
                }
                else if ((string.Equals(resourceId, environment.ActiveDirectoryServiceEndpointResourceId, StringComparison.OrdinalIgnoreCase) ||
                          string.Equals(AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId, resourceId, StringComparison.OrdinalIgnoreCase)) &&
                         account.IsPropertySet(AzureAccount.Property.AccessToken))
                {
                    rawToken.AccessToken = account.GetAccessToken();
                }
                else
                {
                    throw new InvalidOperationException(string.Format(Resources.AccessTokenResourceNotFound, resourceId));
                }

                token = rawToken;
            }
            else if (account.IsPropertySet(AzureAccount.Property.CertificateThumbprint))
            {
                var thumbprint = account.GetProperty(AzureAccount.Property.CertificateThumbprint);
#if !NETSTANDARD
                token = TokenProvider.GetAccessTokenWithCertificate(configuration, account.Id, thumbprint, account.Type);
#else
                throw new NotSupportedException("Certificate based authentication is not supported in netcore version.");
#endif
            }
            else
            {
                token = TokenProvider.GetAccessToken(configuration, promptBehavior, promptAction, account.Id, password, account.Type);
            }

            account.Id = token.UserId;
            return(token);
        }