diff --git a/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs b/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs index b581bf1a6d67..2f4bdd03d58b 100644 --- a/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs +++ b/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs @@ -666,7 +666,7 @@ static string GetJsonText(string text) return result; } - private void WriteWarning(string message) + private void WriteWarningMessage(string message) { EventHandler writeWarningEvent; if (AzureSession.Instance.TryGetComponent(AzureRMCmdlet.WriteWarningKey, out writeWarningEvent)) @@ -675,6 +675,15 @@ private void WriteWarning(string message) } } + private void WriteDebugMessage(string message) + { + EventHandler writeDebugEvent; + if(AzureSession.Instance.TryGetComponent(AzureRMCmdlet.WriteDebugKey, out writeDebugEvent)) + { + writeDebugEvent(this, new StreamEventArgs() { Message = message }); + } + } + private void RefreshContextsFromCache() { var authenticationClientFactory = new SharedTokenCacheClientFactory(); @@ -692,7 +701,7 @@ private void RefreshContextsFromCache() return; } - WriteWarning($"No accounts found in the shared token cache; removing all user contexts."); + WriteWarningMessage($"No accounts found in the shared token cache; removing all user contexts."); var removedContext = false; foreach (var contextName in Contexts.Keys) { @@ -731,7 +740,7 @@ private void RefreshContextsFromCache() if (!removedUsers.Contains(context.Account.Id)) { removedUsers.Add(context.Account.Id); - WriteWarning(string.Format(Resources.UserMissingFromSharedTokenCache, context.Account.Id)); + WriteWarningMessage(string.Format(Resources.UserMissingFromSharedTokenCache, context.Account.Id)); } updatedContext |= TryCacheRemoveContext(contextName); @@ -740,13 +749,13 @@ private void RefreshContextsFromCache() // Check to see if each account has at least one context foreach (var account in accounts) { - if (Contexts.Values.Where(v => v.Account != null && v.Account.Type == AzureAccount.AccountType.User ) + if (Contexts.Values.Where(v => v.Account != null && v.Account.Type == AzureAccount.AccountType.User) .Any(v => string.Equals(v.Account.Id, account.Username, StringComparison.OrdinalIgnoreCase))) { continue; } - WriteWarning(string.Format(Resources.CreatingContextsWarning, account.Username)); + WriteWarningMessage(string.Format(Resources.CreatingContextsWarning, account.Username)); var environment = sessionEnvironment ?? AzureEnvironment.PublicEnvironments .Where(env => env.Value.ActiveDirectoryAuthority.Contains(account.Environment)) .Select(env => env.Value) @@ -757,12 +766,25 @@ private void RefreshContextsFromCache() Type = AzureAccount.AccountType.User }; - var tokens = authenticationClientFactory.GetTenantTokensForAccount(account, environment, WriteWarning); + List tokens = null; + try + { + tokens = authenticationClientFactory.GetTenantTokensForAccount(account, environment, WriteWarningMessage); + } + catch (Exception e) + { + //In SSO scenario, if the account from token cache has multiple tenants, e.g. MSA account, MSAL randomly picks up + //one tenant to ask for token, MSAL will throw exception if MSA home tenant is chosen. The exception is swallowed here as short term fix. + WriteWarningMessage(string.Format(Resources.NoTokenFoundWarning, account.Username)); + WriteDebugMessage(e.ToString()); + continue; + } + foreach (var token in tokens) { var azureTenant = new AzureTenant() { Id = token.TenantId }; azureAccount.SetOrAppendProperty(AzureAccount.Property.Tenants, token.TenantId); - var subscriptions = authenticationClientFactory.GetSubscriptionsFromTenantToken(account, environment, token, WriteWarning); + var subscriptions = authenticationClientFactory.GetSubscriptionsFromTenantToken(account, environment, token, WriteWarningMessage); if (!subscriptions.Any()) { subscriptions.Add(null); @@ -773,13 +795,13 @@ private void RefreshContextsFromCache() var context = new AzureContext(subscription, azureAccount, environment, azureTenant); if (!TryGetContextName(context, out string name)) { - WriteWarning(string.Format(Resources.NoContextNameForSubscription, subscription.Id)); + WriteWarningMessage(string.Format(Resources.NoContextNameForSubscription, subscription.Id)); continue; } if (!TrySetContext(name, context)) { - WriteWarning(string.Format(Resources.UnableToCreateContextForSubscription, subscription.Id)); + WriteWarningMessage(string.Format(Resources.UnableToCreateContextForSubscription, subscription.Id)); } else { diff --git a/src/Accounts/Authentication.ResourceManager/Properties/Resources.Designer.cs b/src/Accounts/Authentication.ResourceManager/Properties/Resources.Designer.cs index 8883bb345015..b91e6864abb0 100644 --- a/src/Accounts/Authentication.ResourceManager/Properties/Resources.Designer.cs +++ b/src/Accounts/Authentication.ResourceManager/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication.ResourceManager.Propert // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -71,7 +71,7 @@ internal static string CertificateNotFoundInStore { } /// - /// Looks up a localized string similar to Creating context for each subscription accessible by account '{0}.. + /// Looks up a localized string similar to Creating context for each subscription accessible by account '{0}'.. /// internal static string CreatingContextsWarning { get { @@ -151,6 +151,15 @@ internal static string NoInternetConnection { } } + /// + /// Looks up a localized string similar to Failed to get token for account '{0}', please run Connect-AzAccount to login.. + /// + internal static string NoTokenFoundWarning { + get { + return ResourceManager.GetString("NoTokenFoundWarning", resourceCulture); + } + } + /// /// Looks up a localized string similar to A valid implementation of IDataStore must be provided.. /// diff --git a/src/Accounts/Authentication.ResourceManager/Properties/Resources.resx b/src/Accounts/Authentication.ResourceManager/Properties/Resources.resx index ccc804f5d4a2..4b89a1af2ec1 100644 --- a/src/Accounts/Authentication.ResourceManager/Properties/Resources.resx +++ b/src/Accounts/Authentication.ResourceManager/Properties/Resources.resx @@ -1,17 +1,17 @@  - @@ -148,6 +148,9 @@ Please connect to internet before executing this cmdlet + + Failed to get token for account '{0}', please run Connect-AzAccount to login. + A valid implementation of IDataStore must be provided.