diff --git a/src/Accounts/Accounts.Test/AutosaveTests.cs b/src/Accounts/Accounts.Test/AutosaveTests.cs index 5d2132eb4c25..5c76e260982c 100644 --- a/src/Accounts/Accounts.Test/AutosaveTests.cs +++ b/src/Accounts/Accounts.Test/AutosaveTests.cs @@ -13,10 +13,6 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -// TODO: Remove IfDef -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; @@ -29,6 +25,7 @@ using Microsoft.Azure.Commands.Profile.Context; using Microsoft.Azure.Commands.ScenarioTest; using Microsoft.Azure.Commands.ResourceManager.Common; +using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients; namespace Microsoft.Azure.Commands.Profile.Test { @@ -49,10 +46,11 @@ void ResetState() TestExecutionHelpers.SetUpSessionAndProfile(); ResourceManagerProfileProvider.InitializeResourceManagerProfile(true); + // prevent token acquisition + AzureRmProfileProvider.Instance.GetProfile().ShouldRefreshContextsFromCache = false; AzureSession.Instance.DataStore = dataStore; AzureSession.Instance.ARMContextSaveMode = ContextSaveMode.Process; AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory(); - AzureSession.Instance.TokenCache = new AuthenticationStoreTokenCache(new AzureTokenCache()); Environment.SetEnvironmentVariable("Azure_PS_Data_Collection", "false"); } @@ -70,9 +68,12 @@ public void EnableAutosaveWhenDisabled() cmdlet.ExecuteCmdlet(); cmdlet.InvokeEndProcessing(); Assert.Equal(ContextSaveMode.CurrentUser, AzureSession.Instance.ARMContextSaveMode); - Assert.Equal(typeof(ProtectedFileTokenCache), AzureSession.Instance.TokenCache.GetType()); Assert.Equal(typeof(ProtectedProfileProvider), AzureRmProfileProvider.Instance.GetType()); } + catch (PlatformNotSupportedException) + { + // swallow exception when test env (Linux server) doesn't support token cache persistence + } finally { ResetState(); @@ -94,9 +95,12 @@ public void EnableAutosaveWhenEnabled() cmdlet.ExecuteCmdlet(); cmdlet.InvokeEndProcessing(); Assert.Equal(ContextSaveMode.CurrentUser, AzureSession.Instance.ARMContextSaveMode); - Assert.Equal(typeof(ProtectedFileTokenCache), AzureSession.Instance.TokenCache.GetType()); Assert.Equal(typeof(ProtectedProfileProvider), AzureRmProfileProvider.Instance.GetType()); } + catch (PlatformNotSupportedException) + { + // swallow exception when test env (Linux server) doesn't support token cache persistence + } finally { ResetState(); @@ -119,7 +123,8 @@ public void DisableAutosaveWhenEnabled() cmdlet.ExecuteCmdlet(); cmdlet.InvokeEndProcessing(); Assert.Equal(ContextSaveMode.Process, AzureSession.Instance.ARMContextSaveMode); - Assert.Equal(typeof(AuthenticationStoreTokenCache), AzureSession.Instance.TokenCache.GetType()); + Assert.True(AzureSession.Instance.TryGetComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, out AuthenticationClientFactory factory)); + Assert.Equal(typeof(InMemoryTokenCacheClientFactory), factory.GetType()); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); } finally @@ -130,7 +135,7 @@ public void DisableAutosaveWhenEnabled() [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] - public void DisableAutoSsaveWhenDisabled() + public void DisableAutoSaveWhenDisabled() { ResetState(); try @@ -142,7 +147,8 @@ public void DisableAutoSsaveWhenDisabled() cmdlet.ExecuteCmdlet(); cmdlet.InvokeEndProcessing(); Assert.Equal(ContextSaveMode.Process, AzureSession.Instance.ARMContextSaveMode); - Assert.Equal(typeof(AuthenticationStoreTokenCache), AzureSession.Instance.TokenCache.GetType()); + Assert.True(AzureSession.Instance.TryGetComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, out AuthenticationClientFactory factory)); + Assert.Equal(typeof(InMemoryTokenCacheClientFactory), factory.GetType()); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); } finally diff --git a/src/Accounts/Accounts.Test/AzureRMProfileTests.cs b/src/Accounts/Accounts.Test/AzureRMProfileTests.cs index 7d368c886256..e2dc4c57a61c 100644 --- a/src/Accounts/Accounts.Test/AzureRMProfileTests.cs +++ b/src/Accounts/Accounts.Test/AzureRMProfileTests.cs @@ -13,10 +13,6 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -// TODO: Remove IfDef -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Factories; using Microsoft.Azure.Commands.Common.Authentication.Models; @@ -497,19 +493,6 @@ public void NoSubscriptionsInListDoesNotThrow() Assert.False(client.TryGetSubscriptionByName(DefaultTenant.ToString(), "random-name", out subValue)); } - [Fact] - [Trait(Category.AcceptanceType, Category.CheckIn)] - public void SetContextPreservesTokenCache() - { - AzureRmProfile profile = null; - AzureContext context = new AzureContext(null, null, null, null); - Assert.Throws(() => profile.SetContextWithCache(context)); - profile = new AzureRmProfile(); - Assert.Throws(() => profile.SetContextWithCache(null)); - profile.SetContextWithCache(context); - Assert.Equal(AzureSession.Instance.TokenCache.CacheData, profile.DefaultContext.TokenCache.CacheData); - } - [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void AzurePSComletMessageQueue() @@ -547,15 +530,15 @@ public void GetAzureRmSubscriptionPaginatedResult() var profile = new AzureRmProfile(); profile.EnvironmentTable.Add("foo", new AzureEnvironment(AzureEnvironment.PublicEnvironments.Values.FirstOrDefault())); profile.DefaultContext = Context; - var cmdlt = new GetAzureRMSubscriptionCommand(); + var cmdlet = new GetAzureRMSubscriptionCommand(); // Setup - cmdlt.DefaultProfile = profile; - cmdlt.CommandRuntime = commandRuntimeMock; + cmdlet.DefaultProfile = profile; + cmdlet.CommandRuntime = commandRuntimeMock; // Act - cmdlt.InvokeBeginProcessing(); - cmdlt.ExecuteCmdlet(); - cmdlt.InvokeEndProcessing(); + cmdlet.InvokeBeginProcessing(); + cmdlet.ExecuteCmdlet(); + cmdlet.InvokeEndProcessing(); var subscriptionName = MockSubscriptionClientFactory.GetSubscriptionNameFromId(secondList[0]); @@ -593,16 +576,16 @@ public void GetAzureRmSubscriptionByIdMultiplePages() var profile = new AzureRmProfile(); profile.EnvironmentTable.Add("foo", new AzureEnvironment(AzureEnvironment.PublicEnvironments.Values.FirstOrDefault())); profile.DefaultContext = Context; - var cmdlt = new GetAzureRMSubscriptionCommand(); + var cmdlet = new GetAzureRMSubscriptionCommand(); // Setup - cmdlt.DefaultProfile = profile; - cmdlt.CommandRuntime = commandRuntimeMock; - cmdlt.SubscriptionId = secondTenantSubscriptions[2]; + cmdlet.DefaultProfile = profile; + cmdlet.CommandRuntime = commandRuntimeMock; + cmdlet.SubscriptionId = secondTenantSubscriptions[2]; // Act - cmdlt.InvokeBeginProcessing(); - cmdlt.ExecuteCmdlet(); - cmdlt.InvokeEndProcessing(); + cmdlet.InvokeBeginProcessing(); + cmdlet.ExecuteCmdlet(); + cmdlet.InvokeEndProcessing(); Assert.True(commandRuntimeMock.OutputPipeline.Count == 1); @@ -643,16 +626,16 @@ public void GetAzureRmSubscriptionByNameMultiplePages() var profile = new AzureRmProfile(); profile.EnvironmentTable.Add("foo", new AzureEnvironment(AzureEnvironment.PublicEnvironments.Values.FirstOrDefault())); profile.DefaultContext = Context; - var cmdlt = new GetAzureRMSubscriptionCommand(); + var cmdlet = new GetAzureRMSubscriptionCommand(); // Setup - cmdlt.DefaultProfile = profile; - cmdlt.CommandRuntime = commandRuntimeMock; - cmdlt.SubscriptionName = subscriptionName; + cmdlet.DefaultProfile = profile; + cmdlet.CommandRuntime = commandRuntimeMock; + cmdlet.SubscriptionName = subscriptionName; // Act - cmdlt.InvokeBeginProcessing(); - cmdlt.ExecuteCmdlet(); - cmdlt.InvokeEndProcessing(); + cmdlet.InvokeBeginProcessing(); + cmdlet.ExecuteCmdlet(); + cmdlet.InvokeEndProcessing(); Assert.True(commandRuntimeMock.OutputPipeline.Count == 1); @@ -696,16 +679,16 @@ public void GetAzureRmSubscriptionManagedService() profile.DefaultContext.Tenant.Id = DefaultTenant.ToString(); profile.DefaultContext.Account.Type = "User"; - var cmdlt = new GetAzureRMSubscriptionCommand(); + var cmdlet = new GetAzureRMSubscriptionCommand(); // Setup - cmdlt.DefaultProfile = profile; - cmdlt.CommandRuntime = commandRuntimeMock; - Assert.Null(cmdlt.TenantId); + cmdlet.DefaultProfile = profile; + cmdlet.CommandRuntime = commandRuntimeMock; + Assert.Null(cmdlet.TenantId); // Act - cmdlt.InvokeBeginProcessing(); - cmdlt.ExecuteCmdlet(); - cmdlt.InvokeEndProcessing(); - Assert.Null(cmdlt.TenantId); + cmdlet.InvokeBeginProcessing(); + cmdlet.ExecuteCmdlet(); + cmdlet.InvokeEndProcessing(); + Assert.Null(cmdlet.TenantId); Assert.True(commandRuntimeMock.OutputPipeline.Count == 8); // TEST WITH MANAGEDSERVICE @@ -722,16 +705,16 @@ public void GetAzureRmSubscriptionManagedService() profile.DefaultContext.Tenant.Id = DefaultTenant.ToString(); profile.DefaultContext.Account.Type = "ManagedService"; - cmdlt = new GetAzureRMSubscriptionCommand(); + cmdlet = new GetAzureRMSubscriptionCommand(); // Setup - cmdlt.DefaultProfile = profile; - cmdlt.CommandRuntime = commandRuntimeMock; - Assert.Null(cmdlt.TenantId); + cmdlet.DefaultProfile = profile; + cmdlet.CommandRuntime = commandRuntimeMock; + Assert.Null(cmdlet.TenantId); // Act - cmdlt.InvokeBeginProcessing(); - cmdlt.ExecuteCmdlet(); - cmdlt.InvokeEndProcessing(); - Assert.NotNull(cmdlt.TenantId); + cmdlet.InvokeBeginProcessing(); + cmdlet.ExecuteCmdlet(); + cmdlet.InvokeEndProcessing(); + Assert.NotNull(cmdlet.TenantId); Assert.True(commandRuntimeMock.OutputPipeline.Count == 4); } @@ -778,7 +761,7 @@ public void ProfileSerializeDeserializeWorks() currentProfile.DefaultContext = new AzureContext(sub, account, environment, tenant); currentProfile.EnvironmentTable[environment.Name] = environment; - currentProfile.DefaultContext.TokenCache = new AzureTokenCache { CacheData = new byte[] { 1, 2, 3, 4, 5, 6, 8, 9, 0 } }; + currentProfile.DefaultContext.TokenCache = null; AzureRmProfile deserializedProfile; // Round-trip the exception: Serialize and de-serialize with a BinaryFormatter @@ -900,9 +883,7 @@ public void SavingProfileWorks() } }, ""VersionProfile"": null, - ""TokenCache"": { - ""CacheData"": ""AgAAAAAAAAA="" - }, + ""TokenCache"": null, ""ExtendedProperties"": {} } }, @@ -945,7 +926,6 @@ public void SavingProfileWorks() }; profile.DefaultContext = new AzureContext(sub, account, environment, tenant); profile.EnvironmentTable[environment.Name] = environment; - profile.DefaultContext.TokenCache = new AuthenticationStoreTokenCache(new AzureTokenCache { CacheData = new byte[] { 1, 2, 3, 4, 5, 6, 8, 9, 0 } }); profile.Save(); string actual = dataStore.ReadFileAsText(path).Substring(1).TrimEnd(new[] { '\0' }); #if NETSTANDARD @@ -1013,7 +993,6 @@ public void LoadingProfileWorks() Assert.Equal("testCloud", profile.DefaultContext.Environment.Name); Assert.Equal("me@contoso.com", profile.DefaultContext.Account.Id); Assert.Equal(AzureAccount.AccountType.User, profile.DefaultContext.Account.Type); - Assert.Null(profile.DefaultContext.TokenCache.CacheData); // token cache is handled by MSAL extensions lib, we don't possess it anymore Assert.Equal(path, profile.ProfilePath); } diff --git a/src/Accounts/Accounts.Test/ContextCmdletTests.cs b/src/Accounts/Accounts.Test/ContextCmdletTests.cs index 562d07f59956..2fb67c79f6e5 100644 --- a/src/Accounts/Accounts.Test/ContextCmdletTests.cs +++ b/src/Accounts/Accounts.Test/ContextCmdletTests.cs @@ -634,7 +634,6 @@ public void ClearMultipleContexts() Assert.NotNull(profile.DefaultContext); Assert.Null(profile.DefaultContext.Account); Assert.Null(profile.DefaultContext.Subscription); - Assert.NotNull(profile.DefaultContext.TokenCache); } [Fact] diff --git a/src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs b/src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs index 99494be0bc58..1fde01006c4e 100644 --- a/src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs +++ b/src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs @@ -33,6 +33,7 @@ using System.Threading; using System.Collections.Concurrent; using System.Threading.Tasks; +using Microsoft.Identity.Client.Extensions.Msal; namespace Microsoft.Azure.Commands.Profile { @@ -485,16 +486,37 @@ public void OnImport() AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => builder); } + AuthenticationClientFactory factory = null; if (autoSaveEnabled) { - AuthenticationClientFactory factory = new SharedTokenCacheClientFactory(); - AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory); + try + { + factory = new SharedTokenCacheClientFactory(); + } + catch (MsalCachePersistenceException) + { + // If token cache persistence is not supported, fall back to in-memory, and print a warning + // Cannot throw exception here because it is not displayed when user runs a cmdlet + // it only shows up when manually ipmo az.accounts, so it's useless + ModifyContext((profile, client) => + { + AzureSession.Modify(session => { + FileUtilities.DataStore = session.DataStore; + session.ARMContextSaveMode = ContextSaveMode.Process; + }); + }); + autoSaveEnabled = false; + WriteInitializationWarnings(Resources.AutosaveNotSupportedWithFallback); + } } - else + + // if autosave is disabled, or the shared factory fails to initialize, we fallback to in memory + if (!autoSaveEnabled) { - AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory(); - AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory); + factory = new InMemoryTokenCacheClientFactory(); + } + AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory); #if DEBUG } catch (Exception) when (TestMockSupport.RunningMocked) diff --git a/src/Accounts/Accounts/Account/DisconnectAzureRmAccount.cs b/src/Accounts/Accounts/Account/DisconnectAzureRmAccount.cs index de2deed4743e..fe07062eaea8 100644 --- a/src/Accounts/Accounts/Account/DisconnectAzureRmAccount.cs +++ b/src/Accounts/Accounts/Account/DisconnectAzureRmAccount.cs @@ -126,7 +126,7 @@ public override void ExecuteCmdlet() { if (GetContextModificationScope() == ContextModificationScope.CurrentUser) { - AzureSession.Instance.AuthenticationFactory.RemoveUser(azureAccount, AzureSession.Instance.TokenCache); + AzureSession.Instance.AuthenticationFactory.RemoveUser(azureAccount, null); } if (AzureRmProfileProvider.Instance.Profile != null) diff --git a/src/Accounts/Accounts/AutoSave/DisableAzureRmContextAutosave.cs b/src/Accounts/Accounts/AutoSave/DisableAzureRmContextAutosave.cs index 4d0fe7725d29..7d37053c4d96 100644 --- a/src/Accounts/Accounts/AutoSave/DisableAzureRmContextAutosave.cs +++ b/src/Accounts/Accounts/AutoSave/DisableAzureRmContextAutosave.cs @@ -13,10 +13,6 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -// TODO: Remove IfDef -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Profile.Common; using Microsoft.Azure.Commands.ResourceManager.Common; @@ -68,7 +64,6 @@ public override void ExecuteCmdlet() void DisableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextAutosaveSettings result) { - var store = session.DataStore; string tokenPath = Path.Combine(session.TokenCacheDirectory, session.TokenCacheFile); result = new ContextAutosaveSettings { @@ -77,19 +72,7 @@ void DisableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextA FileUtilities.DataStore = session.DataStore; session.ARMContextSaveMode = ContextSaveMode.Process; - var memoryCache = session.TokenCache as AuthenticationStoreTokenCache; - if (memoryCache == null) - { - var diskCache = session.TokenCache as ProtectedFileTokenCache; - memoryCache = new AuthenticationStoreTokenCache(new AzureTokenCache()); - if (diskCache != null) - { - memoryCache.CacheData = diskCache.CacheData; - } - - session.TokenCache = memoryCache; - } - + AuthenticationClientFactory authenticationClientFactory = new InMemoryTokenCacheClientFactory(); if (AzureSession.Instance.TryGetComponent( AuthenticationClientFactory.AuthenticationClientFactoryKey, diff --git a/src/Accounts/Accounts/AutoSave/EnableAzureRmContextAutosave.cs b/src/Accounts/Accounts/AutoSave/EnableAzureRmContextAutosave.cs index 18d3b07e96b0..abf6c93d3832 100644 --- a/src/Accounts/Accounts/AutoSave/EnableAzureRmContextAutosave.cs +++ b/src/Accounts/Accounts/AutoSave/EnableAzureRmContextAutosave.cs @@ -13,10 +13,6 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -// TODO: Remove IfDef -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Profile.Common; using Microsoft.Azure.Commands.ResourceManager.Common; @@ -26,6 +22,9 @@ using System.Management.Automation; using Microsoft.Identity.Client; using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients; +using System; +using Microsoft.Identity.Client.Extensions.Msal; +using Microsoft.Azure.Commands.Profile.Properties; namespace Microsoft.Azure.Commands.Profile.Context { @@ -84,30 +83,9 @@ void EnableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextAu FileUtilities.DataStore = session.DataStore; session.ARMContextSaveMode = ContextSaveMode.CurrentUser; - var diskCache = session.TokenCache as ProtectedFileTokenCache; + try { - if (diskCache == null) - { - var memoryCache = session.TokenCache as AuthenticationStoreTokenCache; - try - { - FileUtilities.EnsureDirectoryExists(session.TokenCacheDirectory); - - diskCache = new ProtectedFileTokenCache(tokenPath, store); - if (memoryCache != null) - { - diskCache.CacheData = memoryCache.CacheData; - } - - session.TokenCache = diskCache; - } - catch - { - // leave the token cache alone if there are file system errors - } - } - AuthenticationClientFactory factory = new SharedTokenCacheClientFactory(); AzureSession.Instance.UnregisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey); AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory); @@ -126,9 +104,13 @@ void EnableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextAu } } - catch + catch (Exception e) { // do not throw if there are file system error + if (e is MsalCachePersistenceException) + { + throw new PlatformNotSupportedException(Resources.AutosaveNotSupported); + } } } diff --git a/src/Accounts/Accounts/Az.Accounts.psd1 b/src/Accounts/Accounts/Az.Accounts.psd1 index 2925dc69424b..7a76ac1d9619 100644 --- a/src/Accounts/Accounts/Az.Accounts.psd1 +++ b/src/Accounts/Accounts/Az.Accounts.psd1 @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '1.7.1' +ModuleVersion = '2.0.1' # Supported PSEditions CompatiblePSEditions = 'Core', 'Desktop' @@ -82,12 +82,7 @@ RequiredAssemblies = 'Microsoft.Azure.PowerShell.Authentication.Abstractions.dll 'Microsoft.Azure.PowerShell.Authenticators.dll', 'Microsoft.Extensions.Caching.Abstractions.dll', 'Microsoft.Extensions.Caching.Memory.dll', - 'Microsoft.Extensions.Configuration.Abstractions.dll', - 'Microsoft.Extensions.Configuration.Binder.dll', - 'Microsoft.Extensions.Configuration.dll', - 'Microsoft.Extensions.Configuration.EnvironmentVariables.dll', 'Microsoft.Extensions.DependencyInjection.Abstractions.dll', - 'Microsoft.Extensions.Logging.Abstractions.dll', 'Microsoft.Extensions.Options.dll', 'Microsoft.Extensions.Primitives.dll', 'Microsoft.Identity.Client.dll', @@ -160,7 +155,7 @@ PrivateData = @{ ReleaseNotes = '* Support ADAL token cache migration' # Prerelease string of this module - # Prerelease = '' + Prerelease = 'preview' # Flag to indicate whether the module requires explicit user acceptance for install/update/save # RequireLicenseAcceptance = $false diff --git a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs index 38ee40bab865..3688154ff877 100644 --- a/src/Accounts/Accounts/Context/ClearAzureRmContext.cs +++ b/src/Accounts/Accounts/Context/ClearAzureRmContext.cs @@ -13,10 +13,6 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -// TODO: Remove IfDef -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.Profile.Common; diff --git a/src/Accounts/Accounts/Context/ImportAzureRMContext.cs b/src/Accounts/Accounts/Context/ImportAzureRMContext.cs index 34f1b05d99f2..fc7a3b668c18 100644 --- a/src/Accounts/Accounts/Context/ImportAzureRMContext.cs +++ b/src/Accounts/Accounts/Context/ImportAzureRMContext.cs @@ -17,12 +17,8 @@ using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.Common.Authentication.ResourceManager; using Microsoft.Azure.Commands.Profile.Common; -// TODO: Remove IfDef using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients; -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; using Microsoft.Azure.Commands.Profile.Models.Core; -#endif using Microsoft.Azure.Commands.Profile.Properties; using System; using System.Linq; diff --git a/src/Accounts/Accounts/Context/SetAzureRMContext.cs b/src/Accounts/Accounts/Context/SetAzureRMContext.cs index 141ea63cdd92..b911d4087e58 100644 --- a/src/Accounts/Accounts/Context/SetAzureRMContext.cs +++ b/src/Accounts/Accounts/Context/SetAzureRMContext.cs @@ -86,9 +86,9 @@ public override void ExecuteCmdlet() { SetContextWithOverwritePrompt((profile, client, name) => { - profile.SetContextWithCache(new AzureContext(Context.Subscription, - Context.Account, - Context.Environment, Context.Tenant), name); + profile.TrySetDefaultContext(name, new AzureContext(Context.Subscription, + Context.Account, + Context.Environment, Context.Tenant)); CompleteContextProcessing(profile); }); } diff --git a/src/Accounts/Accounts/Models/AzureRmProfileExtensions.cs b/src/Accounts/Accounts/Models/AzureRmProfileExtensions.cs index d65b9b2a233f..3c6e3b9f959f 100644 --- a/src/Accounts/Accounts/Models/AzureRmProfileExtensions.cs +++ b/src/Accounts/Accounts/Models/AzureRmProfileExtensions.cs @@ -27,7 +27,8 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common public static class AzureRMProfileExtensions { /// - /// Set the context for the current profile, preserving token cache information + /// Set the context for the current profile, preserving token cache information. + /// After MSAL, token cache is no longer stored in contexts. So this method roughly equals to TrySetDefaultContext(). /// /// The profile to change the context for /// The new context, with no token cache information. @@ -42,14 +43,7 @@ public static void SetContextWithCache(this IAzureContextContainer profile, IAzu { throw new ArgumentNullException("newContext", Resources.ContextCannotBeNull); } - - if (newContext.TokenCache != null && newContext.TokenCache.CacheData != null && newContext.TokenCache.CacheData.Length > 0) - { - AzureSession.Instance.TokenCache.CacheData = newContext.TokenCache.CacheData; - } - - newContext.TokenCache = AzureSession.Instance.TokenCache; - + var rmProfile = profile as AzureRmProfile; if (rmProfile != null) { diff --git a/src/Accounts/Accounts/Properties/Resources.Designer.cs b/src/Accounts/Accounts/Properties/Resources.Designer.cs index ec16c1c5dbb3..cf32236b477a 100644 --- a/src/Accounts/Accounts/Properties/Resources.Designer.cs +++ b/src/Accounts/Accounts/Properties/Resources.Designer.cs @@ -114,6 +114,33 @@ internal static string AutosaveDisabledForContextParameter { } } + /// + /// Looks up a localized string similar to Context autosave is not supported in current environment.. + /// + internal static string AutosaveNotSupported { + get { + return ResourceManager.GetString("AutosaveNotSupported", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Context autosave is not supported in current environment and has been disabled temporarily.. + /// + internal static string AutosaveNotSupportedWithFallback { + get { + return ResourceManager.GetString("AutosaveNotSupportedWithFallback", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Context autosave is not supported in current environment. Please disable it using 'Disable-AzContextSave'.. + /// + internal static string AutosaveNotSupportedWithSuggestion { + get { + return ResourceManager.GetString("AutosaveNotSupportedWithSuggestion", resourceCulture); + } + } + /// /// Looks up a localized string similar to Using Autosave scope '{0}'. /// diff --git a/src/Accounts/Accounts/Properties/Resources.resx b/src/Accounts/Accounts/Properties/Resources.resx index 01295f790e49..20cb5f9ab437 100644 --- a/src/Accounts/Accounts/Properties/Resources.resx +++ b/src/Accounts/Accounts/Properties/Resources.resx @@ -492,4 +492,13 @@ The context is invalid. Please login using Connect-AzAccount. + + Context autosave is not supported in current environment. + + + Context autosave is not supported in current environment. Please disable it using 'Disable-AzContextSave'. + + + Context autosave is not supported in current environment and has been disabled temporarily. + \ No newline at end of file diff --git a/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs b/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs index b581bf1a6d67..7aa9bc33880e 100644 --- a/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs +++ b/src/Accounts/Authentication.ResourceManager/AzureRmProfile.cs @@ -27,6 +27,7 @@ using Microsoft.Azure.Commands.Common.Authentication.ResourceManager; using System.Management.Automation; using Microsoft.Azure.Commands.Common.Authentication.ResourceManager.Properties; +using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients; namespace Microsoft.Azure.Commands.Common.Authentication.Models { @@ -206,7 +207,6 @@ private void Initialize(AzureRmProfile profile) foreach (var context in profile.Contexts) { - context.Value.TokenCache = AzureSession.Instance.TokenCache; this.Contexts.Add(context.Key, context.Value); } @@ -677,7 +677,11 @@ private void WriteWarning(string message) private void RefreshContextsFromCache() { - var authenticationClientFactory = new SharedTokenCacheClientFactory(); + // Authentication factory is already registered in `OnImport()` + AzureSession.Instance.TryGetComponent( + AuthenticationClientFactory.AuthenticationClientFactoryKey, + out AuthenticationClientFactory authenticationClientFactory); + string authority = null; if (TryGetEnvironment(AzureSession.Instance.GetProperty(AzureSession.Property.Environment), out IAzureEnvironment sessionEnvironment)) { diff --git a/src/Accounts/Authentication.ResourceManager/AzureRmProfileConverter.cs b/src/Accounts/Authentication.ResourceManager/AzureRmProfileConverter.cs index 020af457c3ff..6ecb564145b5 100644 --- a/src/Accounts/Authentication.ResourceManager/AzureRmProfileConverter.cs +++ b/src/Accounts/Authentication.ResourceManager/AzureRmProfileConverter.cs @@ -15,10 +15,7 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients; -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.ResourceManager.Common.Serialization; using Newtonsoft.Json; @@ -46,8 +43,6 @@ public override bool CanConvert(Type objectType) || objectType == typeof(IAzureTenant) || objectType == typeof(IAzureTokenCache) || objectType == typeof(AzureTokenCache) - || objectType == typeof(ProtectedFileTokenCache) - || objectType == typeof(AuthenticationStoreTokenCache) || objectType == typeof(IAzureContextContainer); } @@ -80,10 +75,8 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist else if (objectType == typeof(IAzureTokenCache)) { var tempResult = serializer.Deserialize(reader); - var cache = AzureSession.Instance.TokenCache; if (_serializeCache && tempResult != null && tempResult.CacheData != null && tempResult.CacheData.Length > 0) { - cache.CacheData = tempResult.CacheData; if (AzureSession.Instance.TryGetComponent( AuthenticationClientFactory.AuthenticationClientFactoryKey, out AuthenticationClientFactory authenticationClientFactory)) @@ -91,8 +84,8 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist authenticationClientFactory.UpdateTokenDataWithoutFlush(tempResult.CacheData); } } - - return cache; + // cache data is not for direct use, so we do not return anything + return null; } else if (objectType == typeof(Dictionary)) { diff --git a/src/Accounts/Authentication.ResourceManager/ContextModelExtensions.cs b/src/Accounts/Authentication.ResourceManager/ContextModelExtensions.cs index dc9f708b617d..461349d370bc 100644 --- a/src/Accounts/Authentication.ResourceManager/ContextModelExtensions.cs +++ b/src/Accounts/Authentication.ResourceManager/ContextModelExtensions.cs @@ -102,7 +102,6 @@ public static void CopyFrom(this IAzureContext context, IAzureContext other) context.Tenant = new AzureTenant(); context.Tenant.CopyFrom(other.Tenant); context.CopyPropertiesFrom(other); - context.TokenCache = AzureSession.Instance.TokenCache; } } diff --git a/src/Accounts/Authentication.ResourceManager/Models/PSAzureContext.cs b/src/Accounts/Authentication.ResourceManager/Models/PSAzureContext.cs index fbede3775848..73d5877202c7 100644 --- a/src/Accounts/Authentication.ResourceManager/Models/PSAzureContext.cs +++ b/src/Accounts/Authentication.ResourceManager/Models/PSAzureContext.cs @@ -13,9 +13,6 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Profile.Common; using System; @@ -78,7 +75,7 @@ public static implicit operator AzureContext(PSAzureContext context) context.Tenant); } - result.TokenCache = context.TokenCache; + result.TokenCache = null; result.VersionProfile = context.VersionProfile; result.CopyPropertiesFrom(context); return result; @@ -103,7 +100,7 @@ public PSAzureContext(IAzureContext context) Environment = context.Environment == null ? null : new PSAzureEnvironment(context.Environment); Subscription = context.Subscription == null ? null : new PSAzureSubscription(context.Subscription); Tenant = context.Tenant == null ? null : new PSAzureTenant(context.Tenant); - TokenCache = context.TokenCache; + TokenCache = null; this.VersionProfile = context.VersionProfile; this.CopyPropertiesFrom(context); } @@ -136,12 +133,6 @@ public PSAzureContext(PSObject other) { Tenant = new PSAzureTenant(property); } - if (other.TryGetProperty(nameof(TokenCache), out property)) - { - AzureTokenCache cache = new AzureTokenCache(); - cache.Populate(property); - TokenCache = new AuthenticationStoreTokenCache(cache); - } VersionProfile = other.GetProperty(nameof(VersionProfile)); this.PopulateExtensions(other); @@ -176,7 +167,11 @@ public PSAzureContext(PSObject other) [Ps1Xml(Label = "TenantId", Target = ViewControl.Table, ScriptBlock = "$_.Tenant.ToString()", Position = 4)] public IAzureTenant Tenant { get; set; } - public IAzureTokenCache TokenCache { get; set; } + /// + /// Moved to due to MSAL. + /// See for how to create client applications. + /// + public IAzureTokenCache TokenCache { get; set; } = null; public string VersionProfile { get; set; } diff --git a/src/Accounts/Authentication.ResourceManager/ProtectedProfileProvider.cs b/src/Accounts/Authentication.ResourceManager/ProtectedProfileProvider.cs index bd5dde899c04..ac50ad186d87 100644 --- a/src/Accounts/Authentication.ResourceManager/ProtectedProfileProvider.cs +++ b/src/Accounts/Authentication.ResourceManager/ProtectedProfileProvider.cs @@ -14,10 +14,7 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -#if NETSTANDARD using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core; -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.Common.Authentication.ResourceManager; using Microsoft.Identity.Client; @@ -27,7 +24,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common { public class ProtectedProfileProvider : AzureRmProfileProvider { - AzureRmProfile _profile = new AzureRmProfile { DefaultContext = new AzureContext { TokenCache = AzureSession.Instance.TokenCache } }; + AzureRmProfile _profile = new AzureRmProfile { DefaultContext = new AzureContext() }; public ProtectedProfileProvider() { @@ -37,35 +34,11 @@ public ProtectedProfileProvider() } } - public override void ResetDefaultProfile() - { - foreach (var context in _profile.Contexts.Values) - { - context.TokenCache.Clear(); - } - - base.ResetDefaultProfile(); - } - public override T GetProfile() { return Profile as T; } - - public override void SetTokenCacheForProfile(IAzureContextContainer profile) - { - base.SetTokenCacheForProfile(profile); - var session = AzureSession.Instance; - var cache = new ProtectedFileTokenCache(Path.Combine(session.TokenCacheDirectory, session.TokenCacheFile), session.DataStore); - session.TokenCache = cache; - if (profile.HasTokenCache()) - { - cache.CacheData = profile.GetTokenCache().CacheData; - } - - profile.SetTokenCache(cache); - } - + public override IAzureContextContainer Profile { get diff --git a/src/Accounts/Authentication.ResourceManager/ResourceManagerProfileProvider.cs b/src/Accounts/Authentication.ResourceManager/ResourceManagerProfileProvider.cs index 24553ede62f7..fd534460a95a 100644 --- a/src/Accounts/Authentication.ResourceManager/ResourceManagerProfileProvider.cs +++ b/src/Accounts/Authentication.ResourceManager/ResourceManagerProfileProvider.cs @@ -14,10 +14,7 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -#if NETSTANDARD using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core; -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.Common.Authentication.ResourceManager; using Microsoft.Identity.Client; @@ -26,30 +23,8 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common { public class ResourceManagerProfileProvider : AzureRmProfileProvider { - AzureRmProfile _profile = new AzureRmProfile { DefaultContext = new AzureContext { TokenCache = AzureSession.Instance.TokenCache } }; - public override void ResetDefaultProfile() - { - foreach (var context in _profile.Contexts.Values) - { - context.TokenCache.Clear(); - } - - base.ResetDefaultProfile(); - } - - public override void SetTokenCacheForProfile(IAzureContextContainer profile) - { - base.SetTokenCacheForProfile(profile); - var cache = new AuthenticationStoreTokenCache(new TokenCache()); - if (profile.HasTokenCache()) - { - cache.CacheData = profile.GetTokenCache().CacheData; - } - - AzureSession.Instance.TokenCache = cache; - profile.SetTokenCache(cache); - } - + AzureRmProfile _profile = new AzureRmProfile { DefaultContext = new AzureContext() }; + public override T GetProfile() { return Profile as T; diff --git a/src/Accounts/Authentication.ResourceManager/Serialization/ModelConversionExtensions.cs b/src/Accounts/Authentication.ResourceManager/Serialization/ModelConversionExtensions.cs index 8b106fd26679..64d82031872e 100644 --- a/src/Accounts/Authentication.ResourceManager/Serialization/ModelConversionExtensions.cs +++ b/src/Accounts/Authentication.ResourceManager/Serialization/ModelConversionExtensions.cs @@ -46,13 +46,7 @@ public static IAzureContext Convert(this LegacyAzureContext context) result.Subscription = context.Subscription.Convert(); result.Tenant = context.Tenant.Convert(); result.Environment = context.Environment.Convert(); - var cache = AzureSession.Instance.TokenCache; - if ( context.TokenCache != null && context.TokenCache.Length > 0) - { - cache.CacheData = context.TokenCache; - } - result.TokenCache = cache; return result; } diff --git a/src/Accounts/Authentication.Test/AzureSessionTests.cs b/src/Accounts/Authentication.Test/AzureSessionTests.cs deleted file mode 100644 index a4de06efc5a9..000000000000 --- a/src/Accounts/Authentication.Test/AzureSessionTests.cs +++ /dev/null @@ -1,60 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Commands.Common.Authentication.Factories; -using Microsoft.Azure.Commands.Common.Authentication.Models; -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; -using System; -using System.Collections.Generic; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Xunit; -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using System.IO; -using Newtonsoft.Json; -using Microsoft.Azure.Commands.ResourceManager.Common; -using Microsoft.Azure.Commands.Common.Authentication.Core; - -namespace Common.Authentication.Test -{ - public class AzureSessionTests - { -#if !NETSTANDARD - [Fact] -#else - [Fact(Skip = "Investigate assert failure.")] -#endif - [Trait(Category.AcceptanceType, Category.CheckIn)] - public void TokenCacheIgnoresInvalidData() - { - var store = new AzureTokenCache { CacheData = new byte[] { 3, 0, 0, 0, 0, 0, 0, 0 } }; - var cache = new AuthenticationStoreTokenCache(store); - Assert.NotEqual(cache.CacheData, store.CacheData); - } - -#if !NETSTANDARD - [Fact] -#else - [Fact(Skip = "Investigate assert failure.")] -#endif - [Trait(Category.AcceptanceType, Category.CheckIn)] - public void TokenCacheUsesValidData() - { - var store = new AzureTokenCache { CacheData = new byte[] { 2, 0, 0, 0, 0, 0, 0, 0 } }; - var cache = new AuthenticationStoreTokenCache(store); - Assert.Equal(cache.CacheData, store.CacheData); - } - - } -} diff --git a/src/Accounts/Authentication.Test/Cmdlets/ConnectAccount.cs b/src/Accounts/Authentication.Test/Cmdlets/ConnectAccount.cs index 01950274f3d7..a25c8e342b3c 100644 --- a/src/Accounts/Authentication.Test/Cmdlets/ConnectAccount.cs +++ b/src/Accounts/Authentication.Test/Cmdlets/ConnectAccount.cs @@ -35,7 +35,6 @@ namespace Common.Authentication.Test.Cmdlets [Cmdlet(VerbsCommunications.Connect, "AzAccount")] public class ConnectAccount : AzureRMCmdlet { - private IAzureTokenCache _cache; private IAzureEnvironment _environment; private IProfileOperations _profile; private PSCredential _credential; @@ -71,12 +70,6 @@ protected override void BeginProcessing() ProtectedFileProvider.CreateFileProvider( Path.Combine(AzureSession.Instance.ARMProfileDirectory, AzureSession.Instance.ARMProfileFile), FileProtection.ExclusiveWrite)); - var context = _profile.DefaultContext; - _cache = AzureSession.Instance.TokenCache; - if (_profile != null && context != null && context.TokenCache != null) - { - _cache = context.TokenCache; - } _environment = AzureEnvironment.PublicEnvironments[EnvironmentName.AzureCloud]; if (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password)) @@ -282,7 +275,6 @@ private void Login( } } - _profile.DefaultContext.TokenCache = _cache; var defaultContext = _profile.DefaultContext; var subscriptions = ListSubscriptions(tenantId).Take(25); foreach (var subscription in subscriptions) @@ -293,7 +285,6 @@ private void Login( }; var tempContext = new AzureContext(subscription, account, environment, tempTenant); - tempContext.TokenCache = _cache; string tempName = null; if (!_profile.TryGetContextName(tempContext, out tempName)) { @@ -408,7 +399,7 @@ private IAccessToken AcquireAccessToken( password, promptBehavior, promptAction, - _cache); + null); } private IEnumerable ListSubscriptions(string tenantIdOrDomain = "") diff --git a/src/Accounts/Authentication.Test/ContextModelTests.cs b/src/Accounts/Authentication.Test/ContextModelTests.cs index b9486bd0d802..9e74bf303015 100644 --- a/src/Accounts/Authentication.Test/ContextModelTests.cs +++ b/src/Accounts/Authentication.Test/ContextModelTests.cs @@ -27,10 +27,7 @@ public class ContextModelTests static IAzureAccount account1 = new AzureAccount { Id="user1@contoso.org"}; static IAzureSubscription subscription1 = new AzureSubscription { Id = Guid.NewGuid().ToString(), Name = "Contoso Subscription 1" }; static IAzureTenant tenant1 = new AzureTenant { Id = Guid.NewGuid().ToString() }; - static IAzureTokenCache cache = new AzureTokenCache(); - IAzureContext context1 = new AzureContext { - TokenCache = cache - }.WithAccount(account1).WithSubscription(subscription1).WithTenant(tenant1); + IAzureContext context1 = new AzureContext().WithAccount(account1).WithSubscription(subscription1).WithTenant(tenant1); [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] diff --git a/src/Accounts/Authentication.Test/LoginTests.cs b/src/Accounts/Authentication.Test/LoginTests.cs index 0eabc3a8769d..bc8f10734651 100644 --- a/src/Accounts/Authentication.Test/LoginTests.cs +++ b/src/Accounts/Authentication.Test/LoginTests.cs @@ -17,9 +17,6 @@ using Hyak.Common; using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif using Microsoft.Azure.Commands.Common.Authentication.Factories; using Microsoft.Azure.Commands.ResourceManager.Common; using Microsoft.Azure.Internal.Subscriptions; @@ -97,7 +94,7 @@ public void LoginWithUsernameAndPassword() public void LoginWithServicePrincipal() { // REQUIRED: - // _tenantId --> Id of the tenant that the service princinpal is registered to + // _tenantId --> Id of the tenant that the service principal is registered to // _userName --> Application id of the service principal // _password --> Secret of the service principal _account = new AzureAccount() { Type = AzureAccount.AccountType.ServicePrincipal }; @@ -142,30 +139,9 @@ private void EnableAutosave(IAzureSession session, bool writeAutoSaveFile, out C FileUtilities.DataStore = session.DataStore; session.ARMContextSaveMode = ContextSaveMode.CurrentUser; - var diskCache = session.TokenCache as ProtectedFileTokenCache; try { - if (diskCache == null) - { - var memoryCache = session.TokenCache as AuthenticationStoreTokenCache; - try - { - FileUtilities.EnsureDirectoryExists(session.TokenCacheDirectory); - - diskCache = new ProtectedFileTokenCache(tokenPath, store); - if (memoryCache != null) - { - diskCache.CacheData = memoryCache.CacheData; - } - - session.TokenCache = diskCache; - } - catch - { - // leave the token cache alone if there are file system errors - } - } - + // TODO: enable auto save with the client factory if (writeAutoSaveFile) { try diff --git a/src/Accounts/Authentication.Test/PSSerializationTests.cs b/src/Accounts/Authentication.Test/PSSerializationTests.cs index 275794f2072b..f0bb00192f91 100644 --- a/src/Accounts/Authentication.Test/PSSerializationTests.cs +++ b/src/Accounts/Authentication.Test/PSSerializationTests.cs @@ -27,6 +27,7 @@ namespace Common.Authentication.Test { + // TODO: these tests are depending on msal token cache. E.g. they will fail if there are tokens in the cache. public class PSSerializationTests { [Fact] @@ -234,20 +235,6 @@ IAzureEnvironment GetDefaultEnvironment() return env; } - IAzureTokenCache GetDefaultTokenCache() - { - var cache = new AzureTokenCache - { -#if !NETSTANDARD - CacheData = new byte[] { 2, 0, 0, 0, 0, 0, 0, 0 } -#else - CacheData = new byte[] { 3, 0, 0, 0, 0, 0, 0, 0 } -#endif - }; - - return cache; - } - IAzureContext GetDefaultContext() { var context = new AzureContext @@ -256,7 +243,7 @@ IAzureContext GetDefaultContext() Environment = GetDefaultEnvironment(), Subscription = GetDefaultSubscription(), Tenant = GetDefaultTenant(), - TokenCache = GetDefaultTokenCache(), + TokenCache = null, VersionProfile = "2017_09_25" }; diff --git a/src/Accounts/Authentication.Test/SessionInitializationTests.cs b/src/Accounts/Authentication.Test/SessionInitializationTests.cs index 7b8abdcd6950..3f3d0c785b11 100644 --- a/src/Accounts/Authentication.Test/SessionInitializationTests.cs +++ b/src/Accounts/Authentication.Test/SessionInitializationTests.cs @@ -13,7 +13,6 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Commands.Common.Authentication.Core; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; @@ -58,7 +57,7 @@ void ResetState() AzureSession.Instance.DataStore = dataStore; AzureSession.Instance.ARMContextSaveMode = ContextSaveMode.Process; AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory(); - AzureSession.Instance.TokenCache = new AuthenticationStoreTokenCache(new AzureTokenCache()); + AzureSession.Instance.TokenCache = null; Environment.SetEnvironmentVariable("Azure_PS_Data_Collection", ""); } @@ -78,8 +77,6 @@ public void DataCollectionSettingPreventsFileWrite() var session = AzureSession.Instance; Assert.NotNull(session); Assert.Equal(ContextSaveMode.Process, session.ARMContextSaveMode); - Assert.NotNull(session.TokenCache); - Assert.Equal(typeof(AuthenticationStoreTokenCache), session.TokenCache.GetType()); Assert.NotNull(AzureRmProfileProvider.Instance); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); store.Verify(f => f.WriteFile(It.IsAny(), It.IsAny()), Times.Once); @@ -103,8 +100,6 @@ public void TestInitializationCannotCheckDirectoryExistence() var session = AzureSession.Instance; Assert.NotNull(session); Assert.Equal(ContextSaveMode.Process, session.ARMContextSaveMode); - Assert.NotNull(session.TokenCache); - Assert.Equal(typeof(AuthenticationStoreTokenCache), session.TokenCache.GetType()); Assert.NotNull(AzureRmProfileProvider.Instance); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); store.Verify(f => f.DirectoryExists(It.IsAny()), Times.AtLeastOnce); @@ -127,8 +122,6 @@ public void TestInitializationCannotCheckFileExistence() var session = AzureSession.Instance; Assert.NotNull(session); Assert.Equal(ContextSaveMode.Process, session.ARMContextSaveMode); - Assert.NotNull(session.TokenCache); - Assert.Equal(typeof(AuthenticationStoreTokenCache), session.TokenCache.GetType()); Assert.NotNull(AzureRmProfileProvider.Instance); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); store.Verify(f => f.FileExists(It.IsAny()), Times.AtLeastOnce); @@ -152,8 +145,6 @@ public void TestInitializationCannotRead() var session = AzureSession.Instance; Assert.NotNull(session); Assert.Equal(ContextSaveMode.Process, session.ARMContextSaveMode); - Assert.NotNull(session.TokenCache); - Assert.Equal(typeof(AuthenticationStoreTokenCache), session.TokenCache.GetType()); Assert.NotNull(AzureRmProfileProvider.Instance); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); store.Verify(f => f.ReadFileAsText(It.IsAny()), Times.AtLeastOnce); @@ -178,8 +169,6 @@ public void TestInitializationCannotCreateDirectory() var session = AzureSession.Instance; Assert.NotNull(session); Assert.Equal(ContextSaveMode.Process, session.ARMContextSaveMode); - Assert.NotNull(session.TokenCache); - Assert.Equal(typeof(AuthenticationStoreTokenCache), session.TokenCache.GetType()); Assert.NotNull(AzureRmProfileProvider.Instance); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); store.Verify(f => f.CreateDirectory(It.IsAny()), Times.AtLeastOnce()); @@ -205,8 +194,6 @@ public void TestInitializationCannotWrite() var session = AzureSession.Instance; Assert.NotNull(session); Assert.Equal(ContextSaveMode.Process, session.ARMContextSaveMode); - Assert.NotNull(session.TokenCache); - Assert.Equal(typeof(AuthenticationStoreTokenCache), session.TokenCache.GetType()); Assert.NotNull(AzureRmProfileProvider.Instance); Assert.Equal(typeof(ResourceManagerProfileProvider), AzureRmProfileProvider.Instance.GetType()); store.Verify(f => f.WriteFile(It.IsAny(), It.IsAny()), Times.AtLeastOnce); diff --git a/src/Accounts/Authentication/Authentication.csproj b/src/Accounts/Authentication/Authentication.csproj index 1eb4cf9c4c80..38f0de432150 100644 --- a/src/Accounts/Authentication/Authentication.csproj +++ b/src/Accounts/Authentication/Authentication.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/src/Accounts/Authentication/Authentication/AuthenticationStoreTokenCache.cs b/src/Accounts/Authentication/Authentication/AuthenticationStoreTokenCache.cs deleted file mode 100644 index a507c37412a2..000000000000 --- a/src/Accounts/Authentication/Authentication/AuthenticationStoreTokenCache.cs +++ /dev/null @@ -1,133 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.Identity.Client; -using System; -using System.Threading; - -#if NETSTANDARD -namespace Microsoft.Azure.Commands.Common.Authentication.Core -#else -namespace Microsoft.Azure.Commands.Common.Authentication -#endif -{ - [Serializable] - public class AuthenticationStoreTokenCache : IAzureTokenCache, IDisposable - { - private object _tokenCache; - - public object GetUserCache() - { - if (_tokenCache == null) - { - var tokenCache = new TokenCache(); - tokenCache.SetBeforeAccess(HandleBeforeAccess); - tokenCache.SetAfterAccess(HandleAfterAccess); - _tokenCache = tokenCache; - } - - return _tokenCache; - } - - private TokenCache UserCache - { - get - { - return (TokenCache)GetUserCache(); - } - } - - IAzureTokenCache _store = new AzureTokenCache(); - public byte[] CacheData - { - get - { - return _store.CacheData; - } - - set - { - _store.CacheData = value; - } - } - - public AuthenticationStoreTokenCache(AzureTokenCache store) : base() - { - if (null == store) - { - throw new ArgumentNullException("store"); - } - - if (store.CacheData != null && store.CacheData.Length > 0) - { - CacheData = store.CacheData; - } - - UserCache.SetBeforeAccess(HandleBeforeAccess); - UserCache.SetAfterAccess(HandleAfterAccess); - } - - /// - /// Create a token cache, copying any data from the given token cache - /// - /// The cache to copy - /// The store to use for persisting state - public AuthenticationStoreTokenCache(TokenCache cache) : base() - { - if (null == cache) - { - throw new ArgumentNullException("Cache"); - } - - UserCache.SetBeforeAccess(HandleBeforeAccess); - UserCache.SetAfterAccess(HandleAfterAccess); - } - - public void HandleBeforeAccess(TokenCacheNotificationArgs args) - { - args.TokenCache.DeserializeMsalV3(_store.CacheData); - } - - public void HandleAfterAccess(TokenCacheNotificationArgs args) - { - if (args.HasStateChanged) - { - _store.CacheData = args.TokenCache.SerializeMsalV3(); - } - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - var cache = Interlocked.Exchange(ref _store, null); - if (cache != null) - { - cache.CacheData = new byte[] { }; - } - } - } - - public void Dispose() - { - Dispose(true); - } - - public void Clear() - { - _tokenCache = null; - } - } -} diff --git a/src/Accounts/Authentication/Authentication/Clients/AuthenticationClientFactory.cs b/src/Accounts/Authentication/Authentication/Clients/AuthenticationClientFactory.cs index 9070a8ed9c33..e43f000e487e 100644 --- a/src/Accounts/Authentication/Authentication/Clients/AuthenticationClientFactory.cs +++ b/src/Accounts/Authentication/Authentication/Clients/AuthenticationClientFactory.cs @@ -292,7 +292,7 @@ private MsalCacheStorage GetCacheStorage(string filePath) attribute1: new KeyValuePair("MsalClientID", "Microsoft.Developer.IdentityService"), attribute2: new KeyValuePair("MsalClientVersion", "1.0.0.0")); var storageCreationProperties = builder.Build(); - return new MsalCacheStorage(storageCreationProperties, new TraceSource("Azure PowerShell")); + return MsalCacheStorage.Create(storageCreationProperties, new TraceSource("Azure PowerShell")); } } } diff --git a/src/Accounts/Authentication/Authentication/Clients/InMemoryTokenCacheClientFactory.cs b/src/Accounts/Authentication/Authentication/Clients/InMemoryTokenCacheClientFactory.cs index c36052fb92c1..369b8fdad523 100644 --- a/src/Accounts/Authentication/Authentication/Clients/InMemoryTokenCacheClientFactory.cs +++ b/src/Accounts/Authentication/Authentication/Clients/InMemoryTokenCacheClientFactory.cs @@ -17,6 +17,10 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients { + /// + /// Factory that creates client app for authenticating with MSAL. + /// Should be accessed using . + /// public class InMemoryTokenCacheClientFactory : AuthenticationClientFactory { private readonly IMemoryCache _memoryCache; diff --git a/src/Accounts/Authentication/Authentication/Clients/SharedTokenCacheClientFactory.cs b/src/Accounts/Authentication/Authentication/Clients/SharedTokenCacheClientFactory.cs index 6b9541a15ba2..2d0709e2e534 100644 --- a/src/Accounts/Authentication/Authentication/Clients/SharedTokenCacheClientFactory.cs +++ b/src/Accounts/Authentication/Authentication/Clients/SharedTokenCacheClientFactory.cs @@ -40,12 +40,28 @@ public override void FlushTokenData() private CacheMigrationSettings _cacheMigrationSettings; - public SharedTokenCacheClientFactory() { } + + /// When the operating system does not support persistence. + public SharedTokenCacheClientFactory() + { + VerifyCachePersistence(); + } /// /// Initialize the client factory with token cache migration settings. Factory will try to migrate the cache before any access to token cache. /// - public SharedTokenCacheClientFactory(CacheMigrationSettings cacheMigrationSettings) => _cacheMigrationSettings = cacheMigrationSettings; + /// When the operating system does not support persistence. + public SharedTokenCacheClientFactory(CacheMigrationSettings cacheMigrationSettings) : this() => + _cacheMigrationSettings = cacheMigrationSettings; + + /// + /// Verify if token cache persistence is available on current system. Throws exception if not. + /// + /// When the operating system does not support persistence. + protected void VerifyCachePersistence() + { + GetCacheHelper(PowerShellClientId).VerifyPersistence(); + } public override void RegisterCache(IClientApplicationBase client) { diff --git a/src/Accounts/Authentication/Authentication/ProtectedFileTokenCache.cs b/src/Accounts/Authentication/Authentication/ProtectedFileTokenCache.cs deleted file mode 100644 index d9aa467f4241..000000000000 --- a/src/Accounts/Authentication/Authentication/ProtectedFileTokenCache.cs +++ /dev/null @@ -1,198 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.Azure.Commands.Common.Authentication.Properties; -using Microsoft.Identity.Client; -using Microsoft.Identity.Client.Extensions.Msal; -using System; -using System.Collections.Generic; -using System.IO; -using System.Management.Automation.Language; -using System.Security.Cryptography; - -namespace Microsoft.Azure.Commands.Common.Authentication.Core -{ - /// - /// An implementation of the MSAL token cache that stores the cache items - /// in the OS-specific protected file. - /// - public class ProtectedFileTokenCache : IAzureTokenCache - { - private static readonly string PowerShellClientId = "1950a258-227b-4e31-a9cf-717495945fc2"; - private static readonly string CacheFileName = "msal.cache"; - private static readonly string CacheFilePath = Path.Combine(SharedUtilities.GetUserRootDirectory(), ".IdentityService", CacheFileName); - private static readonly object fileLock = new object(); - - private static readonly Lazy instance = new Lazy(() => new ProtectedFileTokenCache()); - - private MsalCacheStorage GetMsalCacheStorage() - { - - var builder = new StorageCreationPropertiesBuilder(Path.GetFileName(CacheFilePath), Path.GetDirectoryName(CacheFilePath), PowerShellClientId); - builder = builder.WithMacKeyChain(serviceName: "Microsoft.Developer.IdentityService", accountName: "MSALCache"); - builder = builder.WithLinuxKeyring( - schemaName: "msal.cache", - collection: "default", - secretLabel: "MSALCache", - attribute1: new KeyValuePair("MsalClientID", "Microsoft.Developer.IdentityService"), - attribute2: new KeyValuePair("MsalClientVersion", "1.0.0.0")); - var storageCreationProperties = builder.Build(); - return new MsalCacheStorage(storageCreationProperties, null); - } - - IDataStore _store; - private object _tokenCache; - - public object GetUserCache() - { - if (_tokenCache == null) - { - var tokenCache = new TokenCache(); - tokenCache.SetBeforeAccess(BeforeAccessNotification); - tokenCache.SetAfterAccess(AfterAccessNotification); - _tokenCache = tokenCache; - } - - return _tokenCache; - } - - private TokenCache UserCache - { - get - { - return (TokenCache)GetUserCache(); - } - } - - private byte[] _cacheDataToReturn = null; - private byte[] _cacheDataToSet = null; - - public byte[] CacheData - { - get - { - return _cacheDataToReturn; - } - - set - { - _cacheDataToSet = value; - } - } - - // Initializes the cache against a local file. - // If the file is already present, it loads its content in the MSAL cache - private ProtectedFileTokenCache() - { - _store = AzureSession.Instance.DataStore; - Initialize(CacheFilePath); - } - - public ProtectedFileTokenCache(byte[] inputData, IDataStore store = null) : this(CacheFilePath, store) - { - CacheData = inputData; - } - - public ProtectedFileTokenCache(string cacheFile, IDataStore store = null) - { - _store = store ?? AzureSession.Instance.DataStore; - Initialize(cacheFile); - } - - private void Initialize(string fileName) - { - UserCache.SetAfterAccess(AfterAccessNotification); - UserCache.SetBeforeAccess(BeforeAccessNotification); - } - - // Triggered right before MSAL needs to access the cache. - // Reload the cache from the persistent store in case it changed since the last access. - void BeforeAccessNotification(TokenCacheNotificationArgs args) - { - ReadFileIntoCache(args: args); - } - - // Triggered right after MSAL accessed the cache. - void AfterAccessNotification(TokenCacheNotificationArgs args) - { - // if the access operation resulted in a cache update - EnsureStateSaved(args); - } - - void EnsureStateSaved(TokenCacheNotificationArgs args) - { - if (args != null && args.HasStateChanged) - { - WriteCacheIntoFile(args); - } - } - - private void ReadFileIntoCache(TokenCacheNotificationArgs args, string cacheFileName = null) - { - if (cacheFileName == null) - { - cacheFileName = CacheFileName; - } - - lock (fileLock) - { - if (_store.FileExists(cacheFileName)) - { - var existingData = GetMsalCacheStorage().ReadData(); - if (_cacheDataToSet != null) - { - existingData = _cacheDataToSet; - _cacheDataToSet = null; - } - - if (existingData != null) - { - try - { - args.TokenCache.DeserializeMsalV3(existingData); - } - catch (CryptographicException) - { - _store.DeleteFile(cacheFileName); - } - } - } - } - } - - private void WriteCacheIntoFile(TokenCacheNotificationArgs args, string cacheFileName = null) - { - lock (fileLock) - { - var dataToWrite = args.TokenCache.SerializeMsalV3(); - _cacheDataToReturn = dataToWrite; - if (args.HasStateChanged) - { - GetMsalCacheStorage().WriteData(dataToWrite); - } - } - } - - public void Clear() - { - if (_store.FileExists(CacheFileName)) - { - _store.DeleteFile(CacheFileName); - } - - _cacheDataToReturn = new byte[] { }; - } - } -} diff --git a/src/Accounts/Authentication/AzureSessionInitializer.cs b/src/Accounts/Authentication/AzureSessionInitializer.cs index 4bea6a7bb9c1..c6164be10823 100644 --- a/src/Accounts/Authentication/AzureSessionInitializer.cs +++ b/src/Accounts/Authentication/AzureSessionInitializer.cs @@ -27,9 +27,6 @@ using System.Collections.Generic; using System.Security.Cryptography; using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients; -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Core; -#endif namespace Microsoft.Azure.Commands.Common.Authentication { @@ -65,26 +62,6 @@ public static void CreateOrReplaceSession(IDataStore dataStore) AzureSession.Initialize(() => CreateInstance(dataStore), true); } - static IAzureTokenCache InitializeTokenCache(IDataStore store, string cacheDirectory, string cacheFile, string autoSaveMode) - { - IAzureTokenCache result = new AuthenticationStoreTokenCache(new AzureTokenCache()); - if (autoSaveMode == ContextSaveMode.CurrentUser) - { - try - { - FileUtilities.DataStore = store; - FileUtilities.EnsureDirectoryExists(cacheDirectory); - var cachePath = Path.Combine(cacheDirectory, cacheFile); - result = new ProtectedFileTokenCache(cachePath, store); - } - catch - { - } - } - - return result; - } - static bool MigrateSettings(IDataStore store, string oldProfileDirectory, string newProfileDirectory) { var filesToMigrate = new string[] { ContextAutosaveSettingFileName, @@ -148,11 +125,19 @@ static void MigrateAdalCache(AzureSession session, IDataStore store, string adal return; } - var authenticationClientFactory = new SharedTokenCacheClientFactory(new CacheMigrationSettings + SharedTokenCacheClientFactory authenticationClientFactory; + try { - CacheData = adalData, - CacheFormat = CacheFormat.AdalV3 - }); + authenticationClientFactory = new SharedTokenCacheClientFactory(new CacheMigrationSettings + { + CacheData = adalData, + CacheFormat = CacheFormat.AdalV3 + }); + } + catch (MsalCachePersistenceException) + { + throw new PlatformNotSupportedException(Resources.AutosaveNotSupportedWithSuggestion); + } var client = authenticationClientFactory.CreatePublicClient(); var accounts = client.GetAccountsAsync().ConfigureAwait(false).GetAwaiter().GetResult(); @@ -280,7 +265,6 @@ static IAzureSession CreateInstance(IDataStore dataStore = null) session.TokenCacheDirectory = autoSave.CacheDirectory; session.TokenCacheFile = autoSave.CacheFile; MigrateAdalCache(session, dataStore, oldCachePath, Path.Combine(cachePath, "msal.cache")); - session.TokenCache = InitializeTokenCache(dataStore, session.TokenCacheDirectory, session.TokenCacheFile, autoSave.Mode); InitializeDataCollection(session); session.RegisterComponent(HttpClientOperationsFactory.Name, () => HttpClientOperationsFactory.Create()); return session; diff --git a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs index 4c15b80fcb01..bd9be915fd31 100644 --- a/src/Accounts/Authentication/Factories/AuthenticationFactory.cs +++ b/src/Accounts/Authentication/Factories/AuthenticationFactory.cs @@ -22,6 +22,7 @@ using Microsoft.Azure.Commands.Common.Authentication.Properties; using System.Threading.Tasks; using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients; +using System.Security.Authentication; namespace Microsoft.Azure.Commands.Common.Authentication.Factories { @@ -84,6 +85,18 @@ public IServicePrincipalKeyStore KeyStore public ITokenProvider TokenProvider { get; set; } + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// public IAccessToken Authenticate( IAzureAccount account, IAzureEnvironment environment, @@ -154,7 +167,7 @@ public IAccessToken Authenticate( tenant, password, promptBehavior, promptAction, - AzureSession.Instance.TokenCache, + null, resourceId); } @@ -213,16 +226,11 @@ public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContex try { - var tokenCache = AzureSession.Instance.TokenCache; TracingAdapter.Information( Resources.UPNAuthenticationTrace, context.Account.Id, context.Environment.Name, tenant); - if (context.TokenCache != null && context.TokenCache.CacheData != null && context.TokenCache.CacheData.Length > 0) - { - tokenCache = context.TokenCache; - } var token = Authenticate( context.Account, @@ -231,10 +239,9 @@ public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContex null, ShowDialog.Never, null, - tokenCache, + null, context.Environment.GetTokenAudience(targetEndpoint)); - - + TracingAdapter.Information( Resources.UPNAuthenticationTokenTrace, token.LoginType, @@ -298,38 +305,28 @@ public ServiceClientCredentials GetServiceClientCredentials(IAzureContext contex { TracingAdapter.Information(Resources.UPNAuthenticationTrace, context.Account.Id, context.Environment.Name, tenant); - - // TODO: When we will refactor the code, need to add tracing - /*TracingAdapter.Information(Resources.UPNAuthenticationTokenTrace, - token.LoginType, token.TenantId, token.UserId);*/ - - var tokenCache = AzureSession.Instance.TokenCache; - - if (context.TokenCache != null) - { - tokenCache = context.TokenCache; - } - - ServiceClientCredentials result = null; + + IAccessToken token = null; switch (context.Account.Type) { case AzureAccount.AccountType.ManagedService: - result = new RenewingTokenCredential( - GetManagedServiceToken( - context.Account, - context.Environment, - tenant, - context.Environment.GetTokenAudience(targetEndpoint))); + token = GetManagedServiceToken( + context.Account, + context.Environment, + tenant, + context.Environment.GetTokenAudience(targetEndpoint)); break; case AzureAccount.AccountType.User: case AzureAccount.AccountType.ServicePrincipal: - result = new RenewingTokenCredential(Authenticate(context.Account, context.Environment, tenant, null, ShowDialog.Never, null, context.Environment.GetTokenAudience(targetEndpoint))); + token = Authenticate(context.Account, context.Environment, tenant, null, ShowDialog.Never, null, context.Environment.GetTokenAudience(targetEndpoint)); break; default: throw new NotSupportedException(context.Account.Type.ToString()); } - return result; + TracingAdapter.Information(Resources.UPNAuthenticationTokenTrace, + token.LoginType, token.TenantId, token.UserId); + return new RenewingTokenCredential(token); } catch (Exception ex) { @@ -338,6 +335,11 @@ public ServiceClientCredentials GetServiceClientCredentials(IAzureContext contex } } + /// + /// Remove a user from token cache. + /// + /// + /// This parameter is no longer used. However to keep the API unchanged it's not removed. public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache) { if (account != null && !string.IsNullOrEmpty(account.Id) && !string.IsNullOrWhiteSpace(account.Type)) diff --git a/src/Accounts/Authentication/Properties/Resources.Designer.cs b/src/Accounts/Authentication/Properties/Resources.Designer.cs index 140fec2aa198..78ab6b87463c 100644 --- a/src/Accounts/Authentication/Properties/Resources.Designer.cs +++ b/src/Accounts/Authentication/Properties/Resources.Designer.cs @@ -159,6 +159,15 @@ internal static string AuthenticationClientFactoryNotRegistered { } } + /// + /// Looks up a localized string similar to Context autosave is not supported on current environment. Please disable it using 'Disable-AzContextSave'.. + /// + internal static string AutosaveNotSupportedWithSuggestion { + get { + return ResourceManager.GetString("AutosaveNotSupportedWithSuggestion", resourceCulture); + } + } + /// /// Looks up a localized string similar to .Azure. /// diff --git a/src/Accounts/Authentication/Properties/Resources.resx b/src/Accounts/Authentication/Properties/Resources.resx index 57cda0562bb2..af3fa4ea3889 100644 --- a/src/Accounts/Authentication/Properties/Resources.resx +++ b/src/Accounts/Authentication/Properties/Resources.resx @@ -340,4 +340,7 @@ The environment name '{0}' is not found. + + Context autosave is not supported on current environment. Please disable it using 'Disable-AzContextSave'. + \ No newline at end of file diff --git a/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetCore/Microsoft.Identity.Client.Extensions.Msal.dll b/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetCore/Microsoft.Identity.Client.Extensions.Msal.dll index 9165a707e3d3..16776ce91e13 100644 Binary files a/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetCore/Microsoft.Identity.Client.Extensions.Msal.dll and b/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetCore/Microsoft.Identity.Client.Extensions.Msal.dll differ diff --git a/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetFx/Microsoft.Identity.Client.Extensions.Msal.dll b/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetFx/Microsoft.Identity.Client.Extensions.Msal.dll index ccadc6353537..6c9e76bb1330 100644 Binary files a/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetFx/Microsoft.Identity.Client.Extensions.Msal.dll and b/src/lib/Microsoft.Identity.Client.Extensions.Msal/NetFx/Microsoft.Identity.Client.Extensions.Msal.dll differ diff --git a/src/lib/Microsoft.Identity.Client/NetCore/Microsoft.Identity.Client.dll b/src/lib/Microsoft.Identity.Client/NetCore/Microsoft.Identity.Client.dll index 381fda64b6e9..1998db21836c 100644 Binary files a/src/lib/Microsoft.Identity.Client/NetCore/Microsoft.Identity.Client.dll and b/src/lib/Microsoft.Identity.Client/NetCore/Microsoft.Identity.Client.dll differ diff --git a/src/lib/Microsoft.Identity.Client/NetFx/Microsoft.Identity.Client.dll b/src/lib/Microsoft.Identity.Client/NetFx/Microsoft.Identity.Client.dll index d41a3de53811..d8120cd456e3 100644 Binary files a/src/lib/Microsoft.Identity.Client/NetFx/Microsoft.Identity.Client.dll and b/src/lib/Microsoft.Identity.Client/NetFx/Microsoft.Identity.Client.dll differ diff --git a/tools/Common.Netcore.Dependencies.targets b/tools/Common.Netcore.Dependencies.targets index 983f21823725..dc2b3656e478 100644 --- a/tools/Common.Netcore.Dependencies.targets +++ b/tools/Common.Netcore.Dependencies.targets @@ -3,21 +3,21 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -32,7 +32,7 @@ - $(NugetPackageRoot)microsoft.azure.powershell.storage\1.0.43-preview\tools\ + $(NugetPackageRoot)microsoft.azure.powershell.storage\1.0.44-preview\tools\ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Authentication.Abstractions.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Authentication.Abstractions.1.0.43-preview.nupkg deleted file mode 100644 index 09ae4c359b5d..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Authentication.Abstractions.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Authentication.Abstractions.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Authentication.Abstractions.1.0.44-preview.nupkg new file mode 100644 index 000000000000..cb96e18129a9 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Authentication.Abstractions.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Aks.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Aks.1.0.43-preview.nupkg deleted file mode 100644 index fd971d5a32f6..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Aks.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Aks.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Aks.1.0.44-preview.nupkg new file mode 100644 index 000000000000..bea3a3c1d929 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Aks.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Authorization.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Authorization.1.0.43-preview.nupkg deleted file mode 100644 index 7c286363fd49..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Authorization.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Authorization.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Authorization.1.0.44-preview.nupkg new file mode 100644 index 000000000000..fafc985052c6 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Authorization.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Compute.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Compute.1.0.43-preview.nupkg deleted file mode 100644 index 7d119e29c12d..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Compute.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Compute.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Compute.1.0.44-preview.nupkg new file mode 100644 index 000000000000..577042506216 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Compute.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Graph.Rbac.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Graph.Rbac.1.0.43-preview.nupkg deleted file mode 100644 index d3be94a84c47..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Graph.Rbac.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Graph.Rbac.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Graph.Rbac.1.0.44-preview.nupkg new file mode 100644 index 000000000000..4171e9072ee4 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Graph.Rbac.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.KeyVault.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.KeyVault.1.0.43-preview.nupkg deleted file mode 100644 index 757e2194f058..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.KeyVault.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.KeyVault.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.KeyVault.1.0.44-preview.nupkg new file mode 100644 index 000000000000..8cd7a6c76ab0 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.KeyVault.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Monitor.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Monitor.1.0.43-preview.nupkg deleted file mode 100644 index e63c0d2e2a3c..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Monitor.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Monitor.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Monitor.1.0.44-preview.nupkg new file mode 100644 index 000000000000..7e41f8306e89 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Monitor.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Network.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Network.1.0.43-preview.nupkg deleted file mode 100644 index 722a8af57f0e..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Network.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Network.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Network.1.0.44-preview.nupkg new file mode 100644 index 000000000000..6dc9d4ab7ada Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Network.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.PolicyInsights.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.PolicyInsights.1.0.43-preview.nupkg deleted file mode 100644 index 90e987496827..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.PolicyInsights.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.PolicyInsights.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.PolicyInsights.1.0.44-preview.nupkg new file mode 100644 index 000000000000..2b982cd7255c Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.PolicyInsights.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.ResourceManager.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.ResourceManager.1.0.43-preview.nupkg deleted file mode 100644 index 06cd046a5b5a..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.ResourceManager.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.ResourceManager.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.ResourceManager.1.0.44-preview.nupkg new file mode 100644 index 000000000000..a341bb247e9d Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.ResourceManager.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Storage.Management.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Storage.Management.1.0.43-preview.nupkg deleted file mode 100644 index 0c59cb470d49..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Storage.Management.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Storage.Management.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Storage.Management.1.0.44-preview.nupkg new file mode 100644 index 000000000000..4c1d9c64c50f Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Storage.Management.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Websites.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Websites.1.0.43-preview.nupkg deleted file mode 100644 index 630f15da2cfa..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Websites.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Websites.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Websites.1.0.44-preview.nupkg new file mode 100644 index 000000000000..ae8cb1c306aa Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Clients.Websites.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Common.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Common.1.0.43-preview.nupkg deleted file mode 100644 index 3e59535dc3b1..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Common.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Common.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Common.1.0.44-preview.nupkg new file mode 100644 index 000000000000..b98337987e5c Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Common.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Storage.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Storage.1.0.44-preview.nupkg similarity index 63% rename from tools/LocalFeed/Microsoft.Azure.PowerShell.Storage.1.0.43-preview.nupkg rename to tools/LocalFeed/Microsoft.Azure.PowerShell.Storage.1.0.44-preview.nupkg index 335a5ac40f84..328d8372d3db 100644 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Storage.1.0.43-preview.nupkg and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Storage.1.0.44-preview.nupkg differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Strategies.1.0.43-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Strategies.1.0.43-preview.nupkg deleted file mode 100644 index 3d70fd01f575..000000000000 Binary files a/tools/LocalFeed/Microsoft.Azure.PowerShell.Strategies.1.0.43-preview.nupkg and /dev/null differ diff --git a/tools/LocalFeed/Microsoft.Azure.PowerShell.Strategies.1.0.44-preview.nupkg b/tools/LocalFeed/Microsoft.Azure.PowerShell.Strategies.1.0.44-preview.nupkg new file mode 100644 index 000000000000..4c0761b71555 Binary files /dev/null and b/tools/LocalFeed/Microsoft.Azure.PowerShell.Strategies.1.0.44-preview.nupkg differ diff --git a/tools/ScenarioTest.ResourceManager/Extensions/TestModelExtensions.cs b/tools/ScenarioTest.ResourceManager/Extensions/TestModelExtensions.cs index d7bbf1ddc197..bdf4e6e43d1b 100644 --- a/tools/ScenarioTest.ResourceManager/Extensions/TestModelExtensions.cs +++ b/tools/ScenarioTest.ResourceManager/Extensions/TestModelExtensions.cs @@ -99,7 +99,6 @@ public static bool IsEqual(this IAzureContext context, IAzureContext other) && context.Environment.IsEqual(other.Environment) && context.Subscription.IsEqual(other.Subscription) && context.Tenant.IsEqual(other.Tenant) - && context.TokenCache.IsEqual(other.TokenCache) && string.Equals(context.VersionProfile, other.VersionProfile, StringComparison.OrdinalIgnoreCase)); } diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs b/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs index a5c48f68ddf4..03b1d225a7bb 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs +++ b/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs @@ -70,7 +70,7 @@ public IAccessToken Authenticate( Action promptAction, string resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId) { - return Authenticate(account, environment, tenant, password, promptBehavior, promptAction, AzureSession.Instance.TokenCache, resourceId); + return Authenticate(account, environment, tenant, password, promptBehavior, promptAction, null, resourceId); } public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContext context) diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs b/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs index 10b9a5f78635..898a2e1a30cf 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs +++ b/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs @@ -110,7 +110,7 @@ public IAccessToken Authenticate( Action promptAction, string resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId) { - return Authenticate(account, environment, tenant, password, promptBehavior, promptAction, AzureSession.Instance.TokenCache, resourceId); + return Authenticate(account, environment, tenant, password, promptBehavior, promptAction, null, resourceId); } public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContext context)