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; } } }
/// <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); }
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()); }
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); }
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); }
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); }
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); }
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); } }
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(); }
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); }
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); }