sync source code az.accounts for msal
This commit is contained in:
Родитель
3d074321ff
Коммит
01f9183226
|
@ -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 System;
|
|||
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 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
|
||||
TestExecutionHelpers.SetUpSessionAndProfile();
|
||||
ResourceManagerProfileProvider.InitializeResourceManagerProfile(true);
|
||||
// prevent token acquisition
|
||||
AzureRmProfileProvider.Instance.GetProfile<AzureRmProfile>().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 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
|
||||
[Fact]
|
||||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void DisableAutoSsaveWhenDisabled()
|
||||
public void DisableAutoSaveWhenDisabled()
|
||||
{
|
||||
ResetState();
|
||||
try
|
||||
|
@ -142,7 +147,8 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
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
|
||||
|
|
|
@ -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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
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<ArgumentNullException>(() => profile.SetContextWithCache(context));
|
||||
profile = new AzureRmProfile();
|
||||
Assert.Throws<ArgumentNullException>(() => 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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
|
||||
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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
}
|
||||
},
|
||||
""VersionProfile"": null,
|
||||
""TokenCache"": {
|
||||
""CacheData"": ""AgAAAAAAAAA=""
|
||||
},
|
||||
""TokenCache"": null,
|
||||
""ExtendedProperties"": {}
|
||||
}
|
||||
},
|
||||
|
@ -945,7 +926,6 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
};
|
||||
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
|
||||
|
@ -972,7 +952,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
}
|
||||
},
|
||||
""Context"": {
|
||||
""TokenCache"": ""AgAAAAAAAAA="",
|
||||
""TokenCache"": null,
|
||||
""Account"": {
|
||||
""Id"": ""me@contoso.com"",
|
||||
""Type"": 1,
|
||||
|
@ -1002,11 +982,6 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
}
|
||||
}
|
||||
}";
|
||||
var expectedArray = new byte[] { 2, 0, 0, 0, 0, 0, 0, 0 };
|
||||
#if NETSTANDARD
|
||||
contents = contents.Replace("AgAAAAAAAAA=", "AwAAAAAAAAA=");
|
||||
expectedArray = new byte[] { 3, 0, 0, 0, 0, 0, 0, 0 };
|
||||
#endif
|
||||
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AzureSession.Instance.ARMProfileFile);
|
||||
var dataStore = new MockDataStore();
|
||||
AzureSession.Instance.DataStore = dataStore;
|
||||
|
@ -1018,7 +993,6 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
|
|||
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.Equal(expectedArray, profile.DefaultContext.TokenCache.CacheData);
|
||||
Assert.Equal(path, profile.ProfilePath);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ using Microsoft.Azure.Commands.Profile.Context;
|
|||
using System.Linq;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.ResourceManager;
|
||||
using Microsoft.Azure.Commands.Profile.Common;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Profile.Test
|
||||
{
|
||||
|
@ -196,7 +197,7 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
var profile = CreateMultipleContextProfile();
|
||||
cmdlet.CommandRuntime = commandRuntimeMock;
|
||||
cmdlet.DefaultProfile = profile;
|
||||
cmdlet.ListAvailable = true;
|
||||
cmdlet.MyInvocation.BoundParameters.Add("ListAvailable", true);
|
||||
cmdlet.InvokeBeginProcessing();
|
||||
cmdlet.ExecuteCmdlet();
|
||||
cmdlet.InvokeEndProcessing();
|
||||
|
@ -218,6 +219,8 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void ClearContextSetsDefaultContextName()
|
||||
{
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
var getCmdlet = new GetAzureRMContextCommand();
|
||||
var profile = CreateMultipleContextProfile();
|
||||
var defaultContextName = profile.DefaultContextKey;
|
||||
|
@ -262,8 +265,8 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
cmdlet.CommandRuntime = commandRuntimeMock;
|
||||
cmdlet.DefaultProfile = profile;
|
||||
cmdlet.Force = true;
|
||||
cmdlet.PassThru = true;
|
||||
cmdlet.MyInvocation.BoundParameters.Add("Name", profile.DefaultContextKey);
|
||||
cmdlet.MyInvocation.BoundParameters.Add("PassThru", true);
|
||||
cmdlet.InvokeBeginProcessing();
|
||||
cmdlet.ExecuteCmdlet();
|
||||
cmdlet.InvokeEndProcessing();
|
||||
|
@ -289,8 +292,8 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
var defaultContextKey = profile.DefaultContextKey;
|
||||
cmdlet.CommandRuntime = commandRuntimeMock;
|
||||
cmdlet.DefaultProfile = profile;
|
||||
cmdlet.PassThru = true;
|
||||
cmdlet.MyInvocation.BoundParameters.Add("Name", removedContextKey);
|
||||
cmdlet.MyInvocation.BoundParameters.Add("PassThru", true);
|
||||
cmdlet.InvokeBeginProcessing();
|
||||
cmdlet.ExecuteCmdlet();
|
||||
cmdlet.InvokeEndProcessing();
|
||||
|
@ -610,6 +613,8 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void ClearMultipleContexts()
|
||||
{
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
var cmdlet = new ClearAzureRmContext();
|
||||
var profile = CreateMultipleContextProfile();
|
||||
var defaultContext = profile.DefaultContext;
|
||||
|
@ -629,14 +634,14 @@ namespace Microsoft.Azure.Commands.Profile.Test
|
|||
Assert.NotNull(profile.DefaultContext);
|
||||
Assert.Null(profile.DefaultContext.Account);
|
||||
Assert.Null(profile.DefaultContext.Subscription);
|
||||
Assert.NotNull(profile.DefaultContext.TokenCache);
|
||||
Assert.Equal(AzureSession.Instance.TokenCache.GetType(), profile.DefaultContext.TokenCache.GetType());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void ClearContextNoLogin()
|
||||
{
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
var cmdlet = new ClearAzureRmContext();
|
||||
var profile = new AzureRmProfile();
|
||||
cmdlet.CommandRuntime = commandRuntimeMock;
|
||||
|
|
|
@ -27,6 +27,13 @@ using Microsoft.Azure.Commands.Profile.Properties;
|
|||
using Microsoft.Azure.Commands.Profile.Common;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Factories;
|
||||
using Microsoft.WindowsAzure.Commands.Common;
|
||||
using Microsoft.Azure.PowerShell.Authenticators;
|
||||
using System.IO;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
using System.Threading;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Identity.Client.Extensions.Msal;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Profile
|
||||
{
|
||||
|
@ -57,7 +64,7 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
[Parameter(ParameterSetName = ServicePrincipalParameterSet,
|
||||
Mandatory = true, HelpMessage = "Service Principal Secret")]
|
||||
[Parameter(ParameterSetName = UserWithCredentialParameterSet,
|
||||
Mandatory = true, HelpMessage = "User Password Credential: this is only supported in Windows PowerShell 5.1")]
|
||||
Mandatory = true, HelpMessage = "Username/Password Credential")]
|
||||
public PSCredential Credential { get; set; }
|
||||
|
||||
[Parameter(ParameterSetName = ServicePrincipalCertificateParameterSet,
|
||||
|
@ -172,6 +179,11 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This cmdlet should work even if there isn't a default context
|
||||
/// </summary>
|
||||
protected override bool RequireDefaultContext() { return false; }
|
||||
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
base.BeginProcessing();
|
||||
|
@ -184,6 +196,24 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
string.Format(Resources.UnknownEnvironment, Environment));
|
||||
}
|
||||
}
|
||||
|
||||
// save the target environment so it can be read to get the correct accounts from token cache
|
||||
AzureSession.Instance.SetProperty(AzureSession.Property.Environment, Environment);
|
||||
|
||||
_writeWarningEvent -= WriteWarningSender;
|
||||
_writeWarningEvent += WriteWarningSender;
|
||||
// store the original write warning handler, register a thread safe one
|
||||
AzureSession.Instance.TryGetComponent(WriteWarningKey, out _originalWriteWarning);
|
||||
AzureSession.Instance.UnregisterComponent<EventHandler<StreamEventArgs>>(WriteWarningKey);
|
||||
AzureSession.Instance.RegisterComponent(WriteWarningKey, () => _writeWarningEvent);
|
||||
}
|
||||
|
||||
private event EventHandler<StreamEventArgs> _writeWarningEvent;
|
||||
private event EventHandler<StreamEventArgs> _originalWriteWarning;
|
||||
|
||||
private void WriteWarningSender(object sender, StreamEventArgs args)
|
||||
{
|
||||
_tasks.Enqueue(new Task(() => this.WriteWarning(args.Message)));
|
||||
}
|
||||
|
||||
public override void ExecuteCmdlet()
|
||||
|
@ -241,7 +271,7 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
? builder.Uri.ToString()
|
||||
: envUri;
|
||||
|
||||
if (!this.IsBound(nameof(ManagedServiceHostName)) && !string.IsNullOrWhiteSpace(envUri)
|
||||
if (!this.IsBound(nameof(ManagedServiceHostName)) && !string.IsNullOrWhiteSpace(envUri)
|
||||
&& !this.IsBound(nameof(ManagedServiceSecret)) && !string.IsNullOrWhiteSpace(envSecret))
|
||||
{
|
||||
// set flag indicating this is AppService Managed Identity ad hoc mode
|
||||
|
@ -322,7 +352,14 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
|
||||
SetContextWithOverwritePrompt((localProfile, profileClient, name) =>
|
||||
{
|
||||
WriteObject((PSAzureProfile)profileClient.Login(
|
||||
bool shouldPopulateContextList = true;
|
||||
if (this.IsParameterBound(c => c.SkipContextPopulation))
|
||||
{
|
||||
shouldPopulateContextList = false;
|
||||
}
|
||||
|
||||
profileClient.WarningLog = (message) => _tasks.Enqueue(new Task(() => this.WriteWarning(message)));
|
||||
var task = new Task<AzureRmProfile>( () => profileClient.Login(
|
||||
azureAccount,
|
||||
_environment,
|
||||
Tenant,
|
||||
|
@ -330,13 +367,43 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
subscriptionName,
|
||||
password,
|
||||
SkipValidation,
|
||||
WriteWarning,
|
||||
WriteWarningEvent,
|
||||
name,
|
||||
!SkipContextPopulation.IsPresent));
|
||||
shouldPopulateContextList));
|
||||
task.Start();
|
||||
while (!task.IsCompleted)
|
||||
{
|
||||
HandleActions();
|
||||
Thread.Yield();
|
||||
}
|
||||
|
||||
HandleActions();
|
||||
var result = (PSAzureProfile) (task.ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
WriteObject(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private ConcurrentQueue<Task> _tasks = new ConcurrentQueue<Task>();
|
||||
|
||||
private void HandleActions()
|
||||
{
|
||||
Task task;
|
||||
while (_tasks.TryDequeue(out task))
|
||||
{
|
||||
task.RunSynchronously();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteWarningEvent(string message)
|
||||
{
|
||||
EventHandler<StreamEventArgs> writeWarningEvent;
|
||||
if (AzureSession.Instance.TryGetComponent(WriteWarningKey, out writeWarningEvent))
|
||||
{
|
||||
writeWarningEvent(this, new StreamEventArgs() { Message = message });
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CheckForExistingContext(AzureRmProfile profile, string name)
|
||||
{
|
||||
return name != null && profile?.Contexts != null && profile.Contexts.ContainsKey(name);
|
||||
|
@ -350,13 +417,30 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
name = ContextName;
|
||||
}
|
||||
|
||||
var profile = DefaultProfile as AzureRmProfile;
|
||||
if (!CheckForExistingContext(profile, name)
|
||||
|| Force.IsPresent
|
||||
|| ShouldContinue(string.Format(Resources.ReplaceContextQuery, name),
|
||||
string.Format(Resources.ReplaceContextCaption, name)))
|
||||
AzureRmProfile profile = null;
|
||||
bool? originalShouldRefreshContextsFromCache = null;
|
||||
try
|
||||
{
|
||||
ModifyContext((prof, client) => setContextAction(prof, client, name));
|
||||
profile = DefaultProfile as AzureRmProfile;
|
||||
if (profile != null)
|
||||
{
|
||||
originalShouldRefreshContextsFromCache = profile.ShouldRefreshContextsFromCache;
|
||||
profile.ShouldRefreshContextsFromCache = false;
|
||||
}
|
||||
if (!CheckForExistingContext(profile, name)
|
||||
|| Force.IsPresent
|
||||
|| ShouldContinue(string.Format(Resources.ReplaceContextQuery, name),
|
||||
string.Format(Resources.ReplaceContextCaption, name)))
|
||||
{
|
||||
ModifyContext((prof, client) => setContextAction(prof, client, name));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(profile != null && originalShouldRefreshContextsFromCache.HasValue)
|
||||
{
|
||||
profile.ShouldRefreshContextsFromCache = originalShouldRefreshContextsFromCache.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,13 +465,37 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
|
||||
var autoSaveEnabled = AzureSession.Instance.ARMContextSaveMode == ContextSaveMode.CurrentUser;
|
||||
var autosaveVariable = System.Environment.GetEnvironmentVariable(AzureProfileConstants.AzureAutosaveVariable);
|
||||
bool localAutosave;
|
||||
if(bool.TryParse(autosaveVariable, out localAutosave))
|
||||
|
||||
if(bool.TryParse(autosaveVariable, out bool localAutosave))
|
||||
{
|
||||
autoSaveEnabled = localAutosave;
|
||||
}
|
||||
|
||||
bool shouldModifyContext = false;
|
||||
if (autoSaveEnabled && !SharedTokenCacheClientFactory.SupportCachePersistence(out string message))
|
||||
{
|
||||
// If token cache persistence is not supported, fall back to in-memory, and print a warning
|
||||
// We cannot just throw an exception here because this is called when importing the module
|
||||
autoSaveEnabled = false;
|
||||
WriteInitializationWarnings(Resources.AutosaveNotSupportedWithFallback);
|
||||
WriteInitializationWarnings(message);
|
||||
shouldModifyContext = true;
|
||||
}
|
||||
|
||||
InitializeProfileProvider(autoSaveEnabled);
|
||||
|
||||
if (shouldModifyContext)
|
||||
{
|
||||
ModifyContext((profile, client) =>
|
||||
{
|
||||
AzureSession.Modify(session =>
|
||||
{
|
||||
FileUtilities.DataStore = session.DataStore;
|
||||
session.ARMContextSaveMode = ContextSaveMode.Process;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
IServicePrincipalKeyStore keyStore =
|
||||
// TODO: Remove IfDef
|
||||
#if NETSTANDARD
|
||||
|
@ -396,6 +504,26 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
new AzureRmServicePrincipalKeyStore();
|
||||
#endif
|
||||
AzureSession.Instance.RegisterComponent(ServicePrincipalKeyStore.Name, () => keyStore);
|
||||
|
||||
IAuthenticatorBuilder builder = null;
|
||||
if (!AzureSession.Instance.TryGetComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, out builder))
|
||||
{
|
||||
builder = new DefaultAuthenticatorBuilder();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => builder);
|
||||
}
|
||||
|
||||
AuthenticationClientFactory factory = null;
|
||||
if (autoSaveEnabled)
|
||||
{
|
||||
factory = new SharedTokenCacheClientFactory();
|
||||
}
|
||||
else // if autosave is disabled, or the shared factory fails to initialize, we fallback to in memory
|
||||
{
|
||||
factory = new InMemoryTokenCacheClientFactory();
|
||||
|
||||
}
|
||||
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
#if DEBUG
|
||||
}
|
||||
catch (Exception) when (TestMockSupport.RunningMocked)
|
||||
|
@ -404,5 +532,13 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void EndProcessing()
|
||||
{
|
||||
base.EndProcessing();
|
||||
// unregister the thread-safe write warning, because it won't work out of this cmdlet
|
||||
AzureSession.Instance.UnregisterComponent<EventHandler<StreamEventArgs>>(WriteWarningKey);
|
||||
AzureSession.Instance.RegisterComponent(WriteWarningKey, () => _originalWriteWarning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
{
|
||||
if (GetContextModificationScope() == ContextModificationScope.CurrentUser)
|
||||
{
|
||||
AzureSession.Instance.AuthenticationFactory.RemoveUser(azureAccount, AzureSession.Instance.TokenCache);
|
||||
AzureSession.Instance.AuthenticationFactory.RemoveUser(azureAccount, null);
|
||||
}
|
||||
|
||||
if (AzureRmProfileProvider.Instance.Profile != null)
|
||||
|
|
|
@ -17,13 +17,14 @@
|
|||
<PreLoadAssemblies Include="$(RepoSrc)lib\System.Private.ServiceModel.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\System.Reflection.DispatchProxy.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\System.Security.AccessControl.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\System.Security.Cryptography.ProtectedData.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\System.Security.Permissions.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\System.Security.Principal.Windows.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\System.ServiceModel.Primitives.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\Microsoft.IdentityModel.Clients.ActiveDirectory\NetFx\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\Microsoft.IdentityModel.Clients.ActiveDirectory\NetFx\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" />
|
||||
<NetCoreAssemblies Include="$(RepoSrc)lib\Microsoft.IdentityModel.Clients.ActiveDirectory\NetCore\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" />
|
||||
<NetCoreAssemblies Include="$(RepoSrc)lib\Microsoft.IdentityModel.Clients.ActiveDirectory\NetCore\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\Microsoft.Identity.Client\NetFx\Microsoft.Identity.Client.dll" />
|
||||
<PreLoadAssemblies Include="$(RepoSrc)lib\Microsoft.Identity.Client.Extensions.Msal\NetFx\Microsoft.Identity.Client.Extensions.Msal.dll" />
|
||||
<NetCoreAssemblies Include="$(RepoSrc)lib\Microsoft.Identity.Client\NetCore\Microsoft.Identity.Client.dll" />
|
||||
<NetCoreAssemblies Include="$(RepoSrc)lib\Microsoft.Identity.Client.Extensions.Msal\NetCore\Microsoft.Identity.Client.Extensions.Msal.dll" />
|
||||
<StorageDependencies Include="$(RepoSrc)lib\WindowsAzure.Storage\9.3.0\Microsoft.WindowsAzure.Storage.dll" />
|
||||
<StorageDependencies Include="$(RepoSrc)lib\WindowsAzure.Storage\9.3.0\Microsoft.WindowsAzure.Storage.DataMovement.dll" />
|
||||
</ItemGroup>
|
||||
|
@ -48,12 +49,13 @@
|
|||
<ItemGroup>
|
||||
<EmbeddedResource Include="AzureRmAlias\Mappings.json" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Authentication.ResourceManager\Authentication.ResourceManager.csproj" />
|
||||
<ProjectReference Include="..\Authentication\Authentication.csproj" />
|
||||
<ProjectReference Include="..\Authentication\Authentication.csproj" />
|
||||
<ProjectReference Include="..\Authenticators\Authenticators.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
|
@ -61,7 +63,22 @@
|
|||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
|
|
|
@ -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;
|
||||
|
@ -24,6 +20,8 @@ using Microsoft.WindowsAzure.Commands.Common;
|
|||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using Microsoft.Identity.Client;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Profile.Context
|
||||
{
|
||||
|
@ -31,6 +29,8 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
[OutputType(typeof(ContextAutosaveSettings))]
|
||||
public class DisableAzureRmContextAutosave : AzureContextModificationCmdlet
|
||||
{
|
||||
protected override bool RequireDefaultContext() { return false; }
|
||||
|
||||
public override void ExecuteCmdlet()
|
||||
{
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Scope)) && Scope == ContextModificationScope.Process)
|
||||
|
@ -66,7 +66,6 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
|
||||
void DisableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextAutosaveSettings result)
|
||||
{
|
||||
var store = session.DataStore;
|
||||
string tokenPath = Path.Combine(session.TokenCacheDirectory, session.TokenCacheFile);
|
||||
result = new ContextAutosaveSettings
|
||||
{
|
||||
|
@ -75,19 +74,18 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
|
||||
FileUtilities.DataStore = session.DataStore;
|
||||
session.ARMContextSaveMode = ContextSaveMode.Process;
|
||||
var memoryCache = session.TokenCache as AuthenticationStoreTokenCache;
|
||||
if (memoryCache == null)
|
||||
|
||||
AuthenticationClientFactory authenticationClientFactory = new InMemoryTokenCacheClientFactory();
|
||||
if (AzureSession.Instance.TryGetComponent(
|
||||
AuthenticationClientFactory.AuthenticationClientFactoryKey,
|
||||
out AuthenticationClientFactory OriginalAuthenticationClientFactory))
|
||||
{
|
||||
var diskCache = session.TokenCache as ProtectedFileTokenCache;
|
||||
memoryCache = new AuthenticationStoreTokenCache(new AzureTokenCache());
|
||||
if (diskCache != null && diskCache.Count > 0)
|
||||
{
|
||||
memoryCache.Deserialize(diskCache.Serialize());
|
||||
}
|
||||
|
||||
session.TokenCache = memoryCache;
|
||||
var token = OriginalAuthenticationClientFactory.ReadTokenData();
|
||||
authenticationClientFactory.UpdateTokenDataWithoutFlush(token);
|
||||
authenticationClientFactory.FlushTokenData();
|
||||
}
|
||||
|
||||
AzureSession.Instance.UnregisterComponent<AuthenticationClientFactory>(AuthenticationClientFactory.AuthenticationClientFactoryKey);
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => authenticationClientFactory);
|
||||
if (writeAutoSaveFile)
|
||||
{
|
||||
FileUtilities.EnsureDirectoryExists(session.ProfileDirectory);
|
||||
|
|
|
@ -13,15 +13,13 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
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.Authentication.Clients;
|
||||
using Microsoft.Azure.Commands.Profile.Common;
|
||||
using Microsoft.Azure.Commands.Profile.Properties;
|
||||
using Microsoft.Azure.Commands.ResourceManager.Common;
|
||||
using Microsoft.WindowsAzure.Commands.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
|
||||
|
@ -31,8 +29,15 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
[OutputType(typeof(ContextAutosaveSettings))]
|
||||
public class EnableAzureRmContextAutosave : AzureContextModificationCmdlet
|
||||
{
|
||||
protected override bool RequireDefaultContext() { return false; }
|
||||
|
||||
public override void ExecuteCmdlet()
|
||||
{
|
||||
if (!SharedTokenCacheClientFactory.SupportCachePersistence(out string message))
|
||||
{
|
||||
throw new PlatformNotSupportedException(Resources.AutosaveNotSupported);
|
||||
}
|
||||
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Scope)) && Scope == ContextModificationScope.Process)
|
||||
{
|
||||
ConfirmAction("Autosave the context in the current session", "Current session", () =>
|
||||
|
@ -82,49 +87,24 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
|
||||
FileUtilities.DataStore = session.DataStore;
|
||||
session.ARMContextSaveMode = ContextSaveMode.CurrentUser;
|
||||
var diskCache = session.TokenCache as ProtectedFileTokenCache;
|
||||
try
|
||||
|
||||
AuthenticationClientFactory factory = new SharedTokenCacheClientFactory();
|
||||
AzureSession.Instance.UnregisterComponent<AuthenticationClientFactory>(AuthenticationClientFactory.AuthenticationClientFactoryKey);
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
if (writeAutoSaveFile)
|
||||
{
|
||||
if (diskCache == null)
|
||||
try
|
||||
{
|
||||
var memoryCache = session.TokenCache as AuthenticationStoreTokenCache;
|
||||
try
|
||||
{
|
||||
FileUtilities.EnsureDirectoryExists(session.TokenCacheDirectory);
|
||||
|
||||
diskCache = new ProtectedFileTokenCache(tokenPath, store);
|
||||
if (memoryCache != null && memoryCache.Count > 0)
|
||||
{
|
||||
diskCache.Deserialize(memoryCache.Serialize());
|
||||
}
|
||||
|
||||
session.TokenCache = diskCache;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// leave the token cache alone if there are file system errors
|
||||
}
|
||||
FileUtilities.EnsureDirectoryExists(session.ProfileDirectory);
|
||||
string autoSavePath = Path.Combine(session.ProfileDirectory, ContextAutosaveSettings.AutoSaveSettingsFile);
|
||||
session.DataStore.WriteFile(autoSavePath, JsonConvert.SerializeObject(result));
|
||||
}
|
||||
|
||||
if (writeAutoSaveFile)
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
FileUtilities.EnsureDirectoryExists(session.ProfileDirectory);
|
||||
string autoSavePath = Path.Combine(session.ProfileDirectory, ContextAutosaveSettings.AutoSaveSettingsFile);
|
||||
session.DataStore.WriteFile(autoSavePath, JsonConvert.SerializeObject(result));
|
||||
}
|
||||
catch
|
||||
{
|
||||
// do not fail for file system errors in writing the autosave setting
|
||||
}
|
||||
|
||||
// do not fail for file system errors in writing the autosave setting
|
||||
// it may impact automation environment and module import.
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// do not throw if there are file system error
|
||||
}
|
||||
}
|
||||
|
||||
bool IsValidPath(string path)
|
||||
|
|
|
@ -15,17 +15,28 @@
|
|||
using Microsoft.Azure.Commands.Common.Authentication;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
using Microsoft.Azure.Commands.Profile.Common;
|
||||
using Microsoft.Azure.Commands.Profile.Properties;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Profile.Context
|
||||
{
|
||||
|
||||
[Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ContextAutosaveSetting")]
|
||||
[OutputType(typeof(ContextAutosaveSettings))]
|
||||
public class GetzureRmContextAutosaveSetting : AzureContextModificationCmdlet
|
||||
{
|
||||
const string NoDirectory = "None";
|
||||
|
||||
protected override bool RequireDefaultContext() { return false; }
|
||||
|
||||
public override void ExecuteCmdlet()
|
||||
{
|
||||
if (!SharedTokenCacheClientFactory.SupportCachePersistence(out string message))
|
||||
{
|
||||
WriteDebug(Resources.AutosaveNotSupported);
|
||||
WriteDebug(message);
|
||||
}
|
||||
|
||||
var session = AzureSession.Instance;
|
||||
ContextModificationScope scope;
|
||||
if (MyInvocation.BoundParameters.ContainsKey(nameof(Scope)) && Scope == ContextModificationScope.CurrentUser)
|
||||
|
|
|
@ -72,12 +72,22 @@ RequiredAssemblies = 'Microsoft.Azure.PowerShell.Authentication.Abstractions.dll
|
|||
'Microsoft.Azure.PowerShell.Clients.KeyVault.dll',
|
||||
'Microsoft.Azure.PowerShell.Clients.Websites.dll',
|
||||
'Hyak.Common.dll', 'Microsoft.ApplicationInsights.dll',
|
||||
'Microsoft.Azure.Common.dll', 'Microsoft.Rest.ClientRuntime.dll',
|
||||
'Microsoft.Azure.Common.dll',
|
||||
'Microsoft.Rest.ClientRuntime.dll',
|
||||
'Microsoft.Rest.ClientRuntime.Azure.dll',
|
||||
'Microsoft.WindowsAzure.Storage.dll',
|
||||
'Microsoft.WindowsAzure.Storage.DataMovement.dll',
|
||||
'Microsoft.Azure.PowerShell.Clients.Aks.dll',
|
||||
'Microsoft.Azure.PowerShell.Strategies.dll'
|
||||
'Microsoft.Azure.PowerShell.Strategies.dll',
|
||||
'Microsoft.Azure.PowerShell.Authenticators.dll',
|
||||
'Microsoft.Extensions.Caching.Abstractions.dll',
|
||||
'Microsoft.Extensions.Caching.Memory.dll',
|
||||
'Microsoft.Extensions.DependencyInjection.Abstractions.dll',
|
||||
'Microsoft.Extensions.Options.dll',
|
||||
'Microsoft.Extensions.Primitives.dll',
|
||||
'Microsoft.Identity.Client.dll',
|
||||
'Microsoft.Identity.Client.Extensions.Msal.dll',
|
||||
'System.Runtime.CompilerServices.Unsafe.dll'
|
||||
|
||||
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
|
||||
# ScriptsToProcess = @()
|
||||
|
@ -142,7 +152,7 @@ PrivateData = @{
|
|||
# IconUri = ''
|
||||
|
||||
# ReleaseNotes of this module
|
||||
ReleaseNotes = '* Updated Add-AzEnvironment and Set-AzEnvironment to accept parameters AzureAttestationServiceEndpointResourceId and AzureAttestationServiceEndpointSuffix'
|
||||
ReleaseNotes = '* Support ADAL token cache migration'
|
||||
|
||||
# Prerelease string of this module
|
||||
Prerelease = 'preview'
|
||||
|
|
|
@ -19,6 +19,24 @@
|
|||
-->
|
||||
## Upcoming Release
|
||||
|
||||
## Version 1.7.1
|
||||
* Support ADAL token cache migration
|
||||
|
||||
## Version 2.0.1
|
||||
* Fix a few issues concerning authentication
|
||||
|
||||
## Version 2.0.0-preview
|
||||
* Update to using Microsoft Authentication Library (MSAL)
|
||||
- Enable interactive login support for cross-platform by default
|
||||
- Device code flow login is now the backup option of interactive login fails, or the user provides the `-UseDeviceAuthentication` switch parameter
|
||||
- Enable username/password support for CSP accounts for cross-platform
|
||||
* Support single-sign on scenario using shared token cache
|
||||
- Token cache is now shared with other products, such as Visual Studio 2019 and Azure CLI
|
||||
- Allows users to add/remove accounts in one product and have the changes reflected in another product
|
||||
- `Connect-AzAccount` adds an account to the token cache if not already there
|
||||
- `Remove-AzAccount` removes the account from the token cache and deletes all contexts containing the account
|
||||
- `Clear-AzContext` removes all accounts from the token cache and deletes all contexts
|
||||
|
||||
## Version 1.7.0
|
||||
* Updated Add-AzEnvironment and Set-AzEnvironment to accept parameters AzureAttestationServiceEndpointResourceId and AzureAttestationServiceEndpointSuffix
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.Azure.Commands.Common.Authentication;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Models;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.ResourceManager;
|
||||
using Microsoft.Azure.Commands.Profile.Properties;
|
||||
|
@ -43,7 +44,11 @@ namespace Microsoft.Azure.Commands.Profile.Common
|
|||
{
|
||||
using (var profile = GetDefaultProfile())
|
||||
{
|
||||
contextAction(profile.ToProfile(), new RMProfileClient(profile));
|
||||
var client = new RMProfileClient(profile)
|
||||
{
|
||||
WarningLog = (s) => WriteWarning(s)
|
||||
};
|
||||
contextAction(profile.ToProfile(), client);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +88,7 @@ namespace Microsoft.Azure.Commands.Profile.Common
|
|||
/// <summary>
|
||||
/// Get the context modification scope for the current cmdlet invoication
|
||||
/// </summary>
|
||||
/// <returns>Process if the cmdlet should only change the current process, CurrentUser
|
||||
/// <returns>Process if the cmdlet should only change the current process, CurrentUser
|
||||
/// if any changes should occur globally.</returns>
|
||||
protected virtual ContextModificationScope GetContextModificationScope()
|
||||
{
|
||||
|
@ -193,6 +198,5 @@ namespace Microsoft.Azure.Commands.Profile.Common
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,13 +39,11 @@ namespace Microsoft.Azure.Commands.Common
|
|||
IEventStore _deferredEvents;
|
||||
ICommandRuntime _runtime;
|
||||
TelemetryProvider _telemetry;
|
||||
AdalLogger _logger;
|
||||
internal static readonly string[] ClientHeaders = {"x-ms-client-request-id", "client-request-id", "x-ms-request-id", "request-id" };
|
||||
public AzModule(ICommandRuntime runtime, IEventStore eventHandler)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_deferredEvents = eventHandler;
|
||||
_logger = new AdalLogger(_deferredEvents.GetDebugLogger());
|
||||
_telemetry = TelemetryProvider.Create(
|
||||
_deferredEvents.GetWarningLogger(), _deferredEvents.GetDebugLogger());
|
||||
}
|
||||
|
@ -58,7 +56,6 @@ namespace Microsoft.Azure.Commands.Common
|
|||
{
|
||||
_deferredEvents = store;
|
||||
_runtime = runtime;
|
||||
_logger = new AdalLogger(_deferredEvents.GetDebugLogger()); ;
|
||||
_telemetry = provider;
|
||||
}
|
||||
|
||||
|
@ -72,13 +69,13 @@ namespace Microsoft.Azure.Commands.Common
|
|||
/// <param name="appendStep">a delegate which allows the module to append a step in the HTTP Pipeline</param>
|
||||
public void OnModuleLoad(string resourceId, string moduleName, PipelineChangeDelegate prependStep, PipelineChangeDelegate appendStep)
|
||||
{
|
||||
// this will be called once when the module starts up
|
||||
// this will be called once when the module starts up
|
||||
// the common module can prepend or append steps to the pipeline at this point.
|
||||
prependStep(UniqueId.Instance.SendAsync);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The cmdlet will call this for every event during the pipeline.
|
||||
/// The cmdlet will call this for every event during the pipeline.
|
||||
/// </summary>
|
||||
/// <param name="id">a <c>string</c> containing the name of the event being raised (well-known events are in <see cref="Microsoft.Azure.Commands.Common.Events"/></param>
|
||||
/// <param name="cancellationToken">a <c>CancellationToken</c> indicating if this request is being cancelled.</param>
|
||||
|
@ -223,8 +220,6 @@ namespace Microsoft.Azure.Commands.Common
|
|||
_telemetry?.Flush();
|
||||
_telemetry?.Dispose();
|
||||
_telemetry = null;
|
||||
_logger?.Dispose();
|
||||
_logger = null;
|
||||
_deferredEvents?.Dispose();
|
||||
_deferredEvents = null;
|
||||
}
|
||||
|
|
|
@ -13,18 +13,14 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
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;
|
||||
using Microsoft.Azure.Commands.Profile.Properties;
|
||||
using Microsoft.Azure.Commands.ResourceManager.Common;
|
||||
using Microsoft.IdentityModel.Clients.ActiveDirectory;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Profile.Context
|
||||
{
|
||||
|
@ -38,6 +34,8 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
[Parameter(Mandatory = false, HelpMessage = "Delete all users and groups from the global scope without prompting")]
|
||||
public SwitchParameter Force { get; set; }
|
||||
|
||||
protected override bool RequireDefaultContext() { return false; }
|
||||
|
||||
public override void ExecuteCmdlet()
|
||||
{
|
||||
switch (GetContextModificationScope())
|
||||
|
@ -50,10 +48,10 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
|
||||
break;
|
||||
case ContextModificationScope.CurrentUser:
|
||||
ConfirmAction(Force.IsPresent, Resources.ClearContextUserContinueMessage,
|
||||
Resources.ClearContextUserProcessMessage, Resources.ClearContextUserTarget,
|
||||
ConfirmAction(Force.IsPresent, Resources.ClearContextUserContinueMessage,
|
||||
Resources.ClearContextUserProcessMessage, Resources.ClearContextUserTarget,
|
||||
() => ModifyContext(ClearContext),
|
||||
() =>
|
||||
() =>
|
||||
{
|
||||
var session = AzureSession.Instance;
|
||||
var contextFilePath = Path.Combine(session.ARMProfileDirectory, session.ARMProfileFile);
|
||||
|
@ -74,39 +72,18 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
client.TryRemoveContext(context);
|
||||
}
|
||||
|
||||
var defaultContext = new AzureContext();
|
||||
var cache = AzureSession.Instance.TokenCache;
|
||||
if (GetContextModificationScope() == ContextModificationScope.CurrentUser)
|
||||
AuthenticationClientFactory authenticationClientFactory;
|
||||
if (!AzureSession.Instance.TryGetComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, out authenticationClientFactory))
|
||||
{
|
||||
var fileCache = cache as ProtectedFileTokenCache;
|
||||
if (fileCache == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var session = AzureSession.Instance;
|
||||
fileCache = new ProtectedFileTokenCache(Path.Combine(session.TokenCacheDirectory, session.TokenCacheFile), session.DataStore);
|
||||
fileCache.Clear();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore exceptions from creating a token cache
|
||||
}
|
||||
}
|
||||
|
||||
cache.Clear();
|
||||
WriteWarning(Resources.ClientFactoryNotRegisteredClear);
|
||||
}
|
||||
else
|
||||
{
|
||||
var localCache = cache as AuthenticationStoreTokenCache;
|
||||
if (localCache != null)
|
||||
{
|
||||
localCache.Clear();
|
||||
}
|
||||
authenticationClientFactory.ClearCache();
|
||||
var defaultContext = new AzureContext();
|
||||
profile.TrySetDefaultContext(defaultContext);
|
||||
result = true;
|
||||
}
|
||||
|
||||
defaultContext.TokenCache = cache;
|
||||
profile.TrySetDefaultContext(defaultContext);
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (PassThru.IsPresent)
|
||||
|
|
|
@ -25,6 +25,8 @@ using System;
|
|||
using System.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using Microsoft.Azure.Commands.Profile.Properties;
|
||||
using Microsoft.WindowsAzure.Commands.Utilities.Common;
|
||||
using Microsoft.Azure.Commands.Common.Authentication;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Profile
|
||||
{
|
||||
|
@ -43,7 +45,14 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
{
|
||||
get
|
||||
{
|
||||
if (DefaultProfile == null || DefaultProfile.DefaultContext == null)
|
||||
try
|
||||
{
|
||||
if (DefaultProfile == null || DefaultProfile.DefaultContext == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
@ -55,15 +64,39 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
[Parameter(Mandatory =true, ParameterSetName = ListAllParameterSet, HelpMessage ="List all available contexts in the current session.")]
|
||||
public SwitchParameter ListAvailable { get; set; }
|
||||
|
||||
[Parameter(Mandatory = false, ParameterSetName = ListAllParameterSet, HelpMessage = "Refresh contexts from token cache")]
|
||||
public SwitchParameter RefreshContextFromTokenCache { get; set; }
|
||||
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
// Skip BeginProcessing()
|
||||
}
|
||||
|
||||
public override void ExecuteCmdlet()
|
||||
{
|
||||
if(ListAvailable.IsPresent && RefreshContextFromTokenCache.IsPresent)
|
||||
{
|
||||
try
|
||||
{
|
||||
var defaultProfile = DefaultProfile as AzureRmProfile;
|
||||
if (defaultProfile != null && string.Equals(AzureSession.Instance?.ARMContextSaveMode, "CurrentUser"))
|
||||
{
|
||||
defaultProfile.RefreshContextsFromCache();
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
WriteWarning(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// If no context is found, return
|
||||
if (DefaultContext == null)
|
||||
if (DefaultContext == null && !this.IsParameterBound(c => c.ListAvailable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ListAvailable.IsPresent)
|
||||
if (this.IsParameterBound(c => c.ListAvailable))
|
||||
{
|
||||
var profile = DefaultProfile as AzureRmProfile;
|
||||
if (profile != null && profile.Contexts != null)
|
||||
|
|
|
@ -17,12 +17,8 @@ using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
|||
using Microsoft.Azure.Commands.Common.Authentication.Models;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.ResourceManager;
|
||||
using Microsoft.Azure.Commands.Profile.Common;
|
||||
using Microsoft.Azure.Commands.Profile.Models;
|
||||
// TODO: Remove IfDef
|
||||
#if NETSTANDARD
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Core;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
using Microsoft.Azure.Commands.Profile.Models.Core;
|
||||
#endif
|
||||
using Microsoft.Azure.Commands.Profile.Properties;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
@ -76,29 +72,23 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
target.TrySetDefaultContext(source.DefaultContextKey);
|
||||
}
|
||||
|
||||
AzureRmProfileProvider.Instance.SetTokenCacheForProfile(target.ToProfile());
|
||||
EnsureProtectedCache(target, source.DefaultContext?.TokenCache?.CacheData);
|
||||
EnsureProtectedMsalCache();
|
||||
}
|
||||
|
||||
void EnsureProtectedCache(IProfileOperations profile, byte[] cacheData)
|
||||
void EnsureProtectedMsalCache()
|
||||
{
|
||||
if (profile == null || cacheData == null)
|
||||
try
|
||||
{
|
||||
return;
|
||||
if (AzureSession.Instance.TryGetComponent(
|
||||
AuthenticationClientFactory.AuthenticationClientFactoryKey,
|
||||
out AuthenticationClientFactory authenticationClientFactory))
|
||||
{
|
||||
authenticationClientFactory.FlushTokenData();
|
||||
}
|
||||
}
|
||||
|
||||
AzureRmAutosaveProfile autosave = profile as AzureRmAutosaveProfile;
|
||||
var protectedcache = AzureSession.Instance.TokenCache as ProtectedFileTokenCache;
|
||||
if (autosave != null && protectedcache == null && cacheData.Any())
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
var cache = new ProtectedFileTokenCache(cacheData, AzureSession.Instance.DataStore);
|
||||
}
|
||||
catch
|
||||
{
|
||||
WriteWarning(Resources.ImportAuthenticationFailure);
|
||||
}
|
||||
WriteWarning(Resources.ImportAuthenticationFailure);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +109,7 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
|
||||
ModifyProfile((profile) =>
|
||||
{
|
||||
CopyProfile(new AzureRmProfile(Path), profile);
|
||||
CopyProfile(new AzureRmProfile(Path, false), profile);
|
||||
executionComplete = true;
|
||||
});
|
||||
});
|
||||
|
@ -145,16 +135,17 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
}
|
||||
else
|
||||
{
|
||||
if (profile.DefaultContext != null &&
|
||||
profile.DefaultContext.Subscription != null &&
|
||||
profile.DefaultContext.Subscription.State != null &&
|
||||
!profile.DefaultContext.Subscription.State.Equals(
|
||||
var defaultContext = profile.DefaultContext;
|
||||
if (defaultContext != null &&
|
||||
defaultContext.Subscription != null &&
|
||||
defaultContext.Subscription.State != null &&
|
||||
!defaultContext.Subscription.State.Equals(
|
||||
"Enabled",
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
WriteWarning(string.Format(
|
||||
Microsoft.Azure.Commands.Profile.Properties.Resources.SelectedSubscriptionNotActive,
|
||||
profile.DefaultContext.Subscription.State));
|
||||
defaultContext.Subscription.State));
|
||||
}
|
||||
|
||||
WriteObject((PSAzureProfile)profile);
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
// limitations under the License.
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.Azure.Commands.Common.Authentication;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Models;
|
||||
using Microsoft.Azure.Commands.Profile.Common;
|
||||
using Microsoft.Azure.Commands.Profile.Models;
|
||||
|
@ -20,6 +23,7 @@ using Microsoft.Azure.Commands.Profile.Models;
|
|||
using Microsoft.Azure.Commands.Profile.Models.Core;
|
||||
#endif
|
||||
using Microsoft.Azure.Commands.Profile.Properties;
|
||||
using Microsoft.WindowsAzure.Commands.Utilities.Common;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
|
@ -79,11 +83,31 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
if (profile.Contexts.ContainsKey(name))
|
||||
{
|
||||
var removedContext = profile.Contexts[name];
|
||||
if (client.TryRemoveContext(name) && PassThru.IsPresent)
|
||||
if (client.TryRemoveContext(name))
|
||||
{
|
||||
var outContext = new PSAzureContext(removedContext);
|
||||
outContext.Name = name;
|
||||
WriteObject(outContext);
|
||||
if (removedContext.Account.Type == AzureAccount.AccountType.User &&
|
||||
!profile.Contexts.Any(c => c.Value.Account.Id == removedContext.Account.Id))
|
||||
{
|
||||
AuthenticationClientFactory authenticationClientFactory;
|
||||
if (!AzureSession.Instance.TryGetComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, out authenticationClientFactory))
|
||||
{
|
||||
WriteWarning(string.Format(Resources.ClientFactoryNotRegisteredRemoval, removedContext.Account.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!authenticationClientFactory.TryRemoveAccount(removedContext.Account.Id))
|
||||
{
|
||||
WriteWarning(string.Format(Resources.NoContextsRemain, removedContext.Account.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.IsParameterBound(c => c.PassThru))
|
||||
{
|
||||
var outContext = new PSAzureContext(removedContext);
|
||||
outContext.Name = name;
|
||||
WriteObject(outContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -33,6 +33,11 @@ namespace Microsoft.Azure.Commands.Profile.Context
|
|||
[ValidateNotNullOrEmpty]
|
||||
public PSAzureContext InputObject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This cmdlet should work even if there isn't a default context
|
||||
/// </summary>
|
||||
protected override bool RequireDefaultContext() { return false; }
|
||||
|
||||
public object GetDynamicParameters()
|
||||
{
|
||||
var parameters = new RuntimeDefinedParameterDictionary();
|
||||
|
|
|
@ -86,9 +86,9 @@ namespace Microsoft.Azure.Commands.Profile
|
|||
{
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
public static class AzureRMProfileExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 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().
|
||||
/// </summary>
|
||||
/// <param name="profile">The profile to change the context for</param>
|
||||
/// <param name="newContext">The new context, with no token cache information.</param>
|
||||
|
@ -42,14 +43,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using System.Security;
|
||||
using AuthenticationMessages = Microsoft.Azure.Commands.Common.Authentication.Properties.Resources;
|
||||
using System.Threading.Tasks;
|
||||
using ProfileMessages = Microsoft.Azure.Commands.Profile.Properties.Resources;
|
||||
using ResourceMessages = Microsoft.Azure.Commands.ResourceManager.Common.Properties.Resources;
|
||||
|
||||
|
@ -38,19 +38,11 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
public class RMProfileClient
|
||||
{
|
||||
private IProfileOperations _profile;
|
||||
private IAzureTokenCache _cache;
|
||||
public Action<string> WarningLog;
|
||||
|
||||
public RMProfileClient(IProfileOperations profile)
|
||||
{
|
||||
_profile = profile;
|
||||
var context = _profile.DefaultContext;
|
||||
_cache = AzureSession.Instance.TokenCache;
|
||||
if (_profile != null && context != null &&
|
||||
context.TokenCache != null)
|
||||
{
|
||||
_cache = context.TokenCache;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -252,7 +244,13 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
}
|
||||
}
|
||||
|
||||
shouldPopulateContextList &= _profile.DefaultContext?.Account == null;
|
||||
var populateContextList = true;
|
||||
try
|
||||
{
|
||||
populateContextList = shouldPopulateContextList && _profile.DefaultContext?.Account == null;
|
||||
}
|
||||
catch (PSInvalidOperationException) { }
|
||||
|
||||
if (newSubscription == null)
|
||||
{
|
||||
if (subscriptionId != null)
|
||||
|
@ -286,8 +284,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
}
|
||||
}
|
||||
|
||||
_profile.DefaultContext.TokenCache = _cache;
|
||||
if (shouldPopulateContextList)
|
||||
if (populateContextList)
|
||||
{
|
||||
var defaultContext = _profile.DefaultContext;
|
||||
var subscriptions = ListSubscriptions(tenantId).Take(25);
|
||||
|
@ -299,7 +296,6 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
};
|
||||
|
||||
var tempContext = new AzureContext(subscription, account, environment, tempTenant);
|
||||
tempContext.TokenCache = _cache;
|
||||
string tempName = null;
|
||||
if (!_profile.TryGetContextName(tempContext, out tempName))
|
||||
{
|
||||
|
@ -405,13 +401,13 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
{
|
||||
if (environment == null)
|
||||
{
|
||||
throw new ArgumentNullException("environment", AuthenticationMessages.EnvironmentNeedsToBeSpecified);
|
||||
throw new ArgumentNullException("environment", ProfileMessages.EnvironmentNeedsToBeSpecified);
|
||||
}
|
||||
|
||||
if (AzureEnvironment.PublicEnvironments.ContainsKey(environment.Name))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
string.Format(AuthenticationMessages.ChangingDefaultEnvironmentNotSupported, "environment"));
|
||||
string.Format(ProfileMessages.ChangingDefaultEnvironmentNotSupported, "environment"));
|
||||
}
|
||||
|
||||
IAzureEnvironment result = null;
|
||||
|
@ -439,11 +435,11 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentNullException("name", AuthenticationMessages.EnvironmentNameNeedsToBeSpecified);
|
||||
throw new ArgumentNullException("name", ProfileMessages.EnvironmentNameNeedsToBeSpecified);
|
||||
}
|
||||
if (AzureEnvironment.PublicEnvironments.ContainsKey(name))
|
||||
{
|
||||
throw new ArgumentException(AuthenticationMessages.RemovingDefaultEnvironmentsNotSupported, "name");
|
||||
throw new ArgumentException(ProfileMessages.RemovingDefaultEnvironmentsNotSupported, "name");
|
||||
}
|
||||
|
||||
IAzureEnvironment environment;
|
||||
|
@ -453,7 +449,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(string.Format(AuthenticationMessages.EnvironmentNotFound, name), "name");
|
||||
throw new ArgumentException(string.Format(ProfileMessages.EnvironmentNotFound, name), "name");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,8 +523,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
tenantId,
|
||||
password,
|
||||
promptBehavior,
|
||||
promptAction,
|
||||
_cache);
|
||||
promptAction);
|
||||
}
|
||||
|
||||
private bool TryGetTenantSubscription(IAccessToken accessToken,
|
||||
|
@ -673,7 +668,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteWarningMessage(string.Format(ProfileMessages.UnableToAqcuireToken, commonTenant));
|
||||
if (account.IsPropertySet(AzureAccount.Property.Tenants))
|
||||
|
@ -698,9 +693,11 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
return tenant;
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
if (!result.Any())
|
||||
{
|
||||
throw;
|
||||
WriteWarningMessage("Error occurred when attempting to acquire the common tenant token. Please run 'Connect-AzAccount` again to authenticate.");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
if ($PSEdition -eq 'Desktop') {
|
||||
try {
|
||||
try {
|
||||
[Microsoft.Azure.PowerShell.Authenticators.DesktopAuthenticatorBuilder]::Apply([Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance)
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
[Microsoft.Azure.Commands.Profile.Utilities.CustomAssemblyResolver]::Initialize()
|
||||
} catch {}
|
||||
}
|
|
@ -19,7 +19,7 @@ namespace Microsoft.Azure.Commands.Profile.Properties {
|
|||
// 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", "15.0.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
@ -114,6 +114,33 @@ namespace Microsoft.Azure.Commands.Profile.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Context autosave is not supported in current environment..
|
||||
/// </summary>
|
||||
internal static string AutosaveNotSupported {
|
||||
get {
|
||||
return ResourceManager.GetString("AutosaveNotSupported", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Context autosave is not supported in current environment and has been disabled temporarily..
|
||||
/// </summary>
|
||||
internal static string AutosaveNotSupportedWithFallback {
|
||||
get {
|
||||
return ResourceManager.GetString("AutosaveNotSupportedWithFallback", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Context autosave is not supported in current environment. Please disable it using 'Disable-AzContextSave'..
|
||||
/// </summary>
|
||||
internal static string AutosaveNotSupportedWithSuggestion {
|
||||
get {
|
||||
return ResourceManager.GetString("AutosaveNotSupportedWithSuggestion", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Using Autosave scope '{0}'.
|
||||
/// </summary>
|
||||
|
@ -231,6 +258,15 @@ namespace Microsoft.Azure.Commands.Profile.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Changing public environment is not supported..
|
||||
/// </summary>
|
||||
internal static string ChangingDefaultEnvironmentNotSupported {
|
||||
get {
|
||||
return ResourceManager.GetString("ChangingDefaultEnvironmentNotSupported", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Remove all accounts and subscriptions for the current process..
|
||||
/// </summary>
|
||||
|
@ -276,6 +312,24 @@ namespace Microsoft.Azure.Commands.Profile.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No authentication client factory has been registered, unable to clear the cache..
|
||||
/// </summary>
|
||||
internal static string ClientFactoryNotRegisteredClear {
|
||||
get {
|
||||
return ResourceManager.GetString("ClientFactoryNotRegisteredClear", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No authentication client factory has been registered, unable to remove contexts for user '{0}'..
|
||||
/// </summary>
|
||||
internal static string ClientFactoryNotRegisteredRemoval {
|
||||
get {
|
||||
return ResourceManager.GetString("ClientFactoryNotRegisteredRemoval", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Could not authenticate your user account {0} with the common tenant. Please login again using Connect-AzAccount..
|
||||
/// </summary>
|
||||
|
@ -420,6 +474,33 @@ namespace Microsoft.Azure.Commands.Profile.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Environment name needs to be specified.
|
||||
/// </summary>
|
||||
internal static string EnvironmentNameNeedsToBeSpecified {
|
||||
get {
|
||||
return ResourceManager.GetString("EnvironmentNameNeedsToBeSpecified", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Environment needs to be specified.
|
||||
/// </summary>
|
||||
internal static string EnvironmentNeedsToBeSpecified {
|
||||
get {
|
||||
return ResourceManager.GetString("EnvironmentNeedsToBeSpecified", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The environment name '{0}' is not found..
|
||||
/// </summary>
|
||||
internal static string EnvironmentNotFound {
|
||||
get {
|
||||
return ResourceManager.GetString("EnvironmentNotFound", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to retrieve variable value '{0}' to determine AutoSaveSetting, received exception '{1}'..
|
||||
/// </summary>
|
||||
|
@ -537,6 +618,15 @@ namespace Microsoft.Azure.Commands.Profile.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No contexts remain for user '{0}'..
|
||||
/// </summary>
|
||||
internal static string NoContextsRemain {
|
||||
get {
|
||||
return ResourceManager.GetString("NoContextsRemain", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Please provide a valid tenant Id on the command line or execute Connect-AzAccount..
|
||||
/// </summary>
|
||||
|
@ -708,6 +798,15 @@ namespace Microsoft.Azure.Commands.Profile.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Removing public environment is not supported..
|
||||
/// </summary>
|
||||
internal static string RemovingDefaultEnvironmentsNotSupported {
|
||||
get {
|
||||
return ResourceManager.GetString("RemovingDefaultEnvironmentsNotSupported", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Rename context '{0}' to '{1}'.
|
||||
/// </summary>
|
||||
|
|
|
@ -465,7 +465,40 @@
|
|||
<data name="SovereignProfileDescription" xml:space="preserve">
|
||||
<value>A snapshot of the service API versiosn available in Azure Sovereign Clouds and the Azure Global Cloud.</value>
|
||||
</data>
|
||||
<data name="ClientFactoryNotRegisteredClear" xml:space="preserve">
|
||||
<value>No authentication client factory has been registered, unable to clear the cache.</value>
|
||||
</data>
|
||||
<data name="ClientFactoryNotRegisteredRemoval" xml:space="preserve">
|
||||
<value>No authentication client factory has been registered, unable to remove contexts for user '{0}'.</value>
|
||||
</data>
|
||||
<data name="NoContextsRemain" xml:space="preserve">
|
||||
<value>No contexts remain for user '{0}'.</value>
|
||||
</data>
|
||||
<data name="ChangingDefaultEnvironmentNotSupported" xml:space="preserve">
|
||||
<value>Changing public environment is not supported.</value>
|
||||
</data>
|
||||
<data name="EnvironmentNameNeedsToBeSpecified" xml:space="preserve">
|
||||
<value>Environment name needs to be specified</value>
|
||||
</data>
|
||||
<data name="EnvironmentNeedsToBeSpecified" xml:space="preserve">
|
||||
<value>Environment needs to be specified</value>
|
||||
</data>
|
||||
<data name="EnvironmentNotFound" xml:space="preserve">
|
||||
<value>The environment name '{0}' is not found.</value>
|
||||
</data>
|
||||
<data name="RemovingDefaultEnvironmentsNotSupported" xml:space="preserve">
|
||||
<value>Removing public environment is not supported.</value>
|
||||
</data>
|
||||
<data name="InvalidAzureContext" xml:space="preserve">
|
||||
<value>The context is invalid. Please login using Connect-AzAccount.</value>
|
||||
</data>
|
||||
<data name="AutosaveNotSupported" xml:space="preserve">
|
||||
<value>Context autosave is not supported in current environment.</value>
|
||||
</data>
|
||||
<data name="AutosaveNotSupportedWithSuggestion" xml:space="preserve">
|
||||
<value>Context autosave is not supported in current environment. Please disable it using 'Disable-AzContextSave'.</value>
|
||||
</data>
|
||||
<data name="AutosaveNotSupportedWithFallback" xml:space="preserve">
|
||||
<value>Context autosave is not supported in current environment and has been disabled temporarily.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Profile.Utilities
|
||||
{
|
||||
public static class CustomAssemblyResolver
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When the resolution of an assembly fails, if it's Newtonsoft.Json 9, redirect to 10
|
||||
/// </summary>
|
||||
public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
AssemblyName name = new AssemblyName(args.Name);
|
||||
if(string.Equals(name.Name, "Newtonsoft.Json", StringComparison.OrdinalIgnoreCase)
|
||||
&& name.Version?.Major == 9)
|
||||
{
|
||||
string accountFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
string newtonsoftJsonPath = Path.Combine(accountFolder, @"PreloadAssemblies\Newtonsoft.Json.10.dll");
|
||||
return Assembly.LoadFrom(newtonsoftJsonPath);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -201,7 +201,7 @@ Aliases:
|
|||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept pipeline input: True (ByPropertyName)
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
|
@ -216,7 +216,7 @@ Aliases:
|
|||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept pipeline input: True (ByPropertyName)
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
|
@ -582,7 +582,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ Gets tenants that are authorized for the current user.
|
|||
Loads Azure authentication information from a file.
|
||||
|
||||
### [Register-AzModule](Register-AzModule.md)
|
||||
FOR INTERNAL USE ONLY - Provide Runtime Support for AutoRest Generated cmdlets.
|
||||
FOR INTERNAL USE ONLY - Provide Runtime Support for AutoRest Generated cmdlets
|
||||
|
||||
### [Remove-AzContext](Remove-AzContext.md)
|
||||
Remove a context from the set of available contexts
|
||||
|
|
|
@ -124,7 +124,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -607,7 +607,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ Get-AzContext [-DefaultProfile <IAzureContextContainer>] [[-Name] <String>] [<Co
|
|||
|
||||
### ListAllContexts
|
||||
```
|
||||
Get-AzContext [-ListAvailable] [-DefaultProfile <IAzureContextContainer>] [<CommonParameters>]
|
||||
Get-AzContext [-ListAvailable] [-RefreshContextFromTokenCache] [-DefaultProfile <IAzureContextContainer>]
|
||||
[<CommonParameters>]
|
||||
```
|
||||
|
||||
## DESCRIPTION
|
||||
|
@ -101,8 +102,23 @@ Accept pipeline input: False
|
|||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -RefreshContextFromTokenCache
|
||||
Refresh contexts from token cache
|
||||
|
||||
```yaml
|
||||
Type: System.Management.Automation.SwitchParameter
|
||||
Parameter Sets: ListAllContexts
|
||||
Aliases:
|
||||
|
||||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -183,6 +183,7 @@ Default value: None
|
|||
Accept pipeline input: False
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
### -AzureAttestationServiceEndpointResourceId
|
||||
The The resource identifier of the Azure Attestation service that is the recipient of the requested token.
|
||||
|
||||
|
@ -194,7 +195,7 @@ Aliases:
|
|||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept pipeline input: True (ByPropertyName)
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
|
@ -209,7 +210,7 @@ Aliases:
|
|||
Required: False
|
||||
Position: Named
|
||||
Default value: None
|
||||
Accept pipeline input: False
|
||||
Accept pipeline input: True (ByPropertyName)
|
||||
Accept wildcard characters: False
|
||||
```
|
||||
|
||||
|
@ -575,7 +576,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ Accept wildcard characters: False
|
|||
```
|
||||
|
||||
### CommonParameters
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||
|
||||
## INPUTS
|
||||
|
||||
|
|
|
@ -15,4 +15,19 @@
|
|||
<ProjectReference Include="..\Authentication\Authentication.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -25,6 +25,9 @@ using System.Xml.Serialization;
|
|||
using Microsoft.Azure.Commands.ResourceManager.Common.Serialization;
|
||||
using System.Collections.Concurrent;
|
||||
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
|
||||
{
|
||||
|
@ -42,6 +45,10 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
|
||||
public IDictionary<string, IAzureContext> Contexts { get; set; } = new ConcurrentDictionary<string, IAzureContext>(StringComparer.CurrentCultureIgnoreCase);
|
||||
|
||||
[JsonIgnore]
|
||||
[XmlIgnore]
|
||||
public bool ShouldRefreshContextsFromCache { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path of the profile file.
|
||||
/// </summary>
|
||||
|
@ -58,11 +65,28 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
{
|
||||
get
|
||||
{
|
||||
//TODO: remove calling RefreshContextsFromCache
|
||||
if (ShouldRefreshContextsFromCache && AzureSession.Instance != null && AzureSession.Instance.ARMContextSaveMode == "CurrentUser")
|
||||
{
|
||||
// If context autosave is enabled, try reading from the cache, updating the contexts, and writing them out
|
||||
RefreshContextsFromCache();
|
||||
}
|
||||
|
||||
IAzureContext result = null;
|
||||
if (DefaultContextKey == "Default" && Contexts.Any(c => c.Key != "Default"))
|
||||
{
|
||||
// If the default context is "Default", but there are other contexts set, remove the "Default" context to throw the below exception
|
||||
TryCacheRemoveContext("Default");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(DefaultContextKey) && Contexts != null && Contexts.ContainsKey(DefaultContextKey))
|
||||
{
|
||||
result = this.Contexts[DefaultContextKey];
|
||||
}
|
||||
else if (DefaultContextKey == null)
|
||||
{
|
||||
throw new PSInvalidOperationException(Resources.DefaultContextMissing);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -184,11 +208,10 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
|
||||
foreach (var context in profile.Contexts)
|
||||
{
|
||||
context.Value.TokenCache = AzureSession.Instance.TokenCache;
|
||||
this.Contexts.Add(context.Key, context.Value);
|
||||
}
|
||||
|
||||
DefaultContextKey = profile.DefaultContextKey ?? "Default";
|
||||
DefaultContextKey = profile.DefaultContextKey ?? (profile.Contexts.Any() ? null : "Default");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,8 +238,9 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
/// Initializes a new instance of AzureRMProfile and loads its content from specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The location of profile file on disk.</param>
|
||||
public AzureRmProfile(string path) : this()
|
||||
public AzureRmProfile(string path, bool shouldRefreshContextsFromCache = true) : this()
|
||||
{
|
||||
this.ShouldRefreshContextsFromCache = shouldRefreshContextsFromCache;
|
||||
Load(path);
|
||||
}
|
||||
|
||||
|
@ -244,7 +268,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
/// Writes profile to a specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">File path on disk to save profile to</param>
|
||||
public void Save(string path)
|
||||
public void Save(string path, bool serializeCache = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
|
@ -253,7 +277,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
|
||||
using (var provider = ProtectedFileProvider.CreateFileProvider(path, FileProtection.ExclusiveWrite))
|
||||
{
|
||||
Save(provider);
|
||||
Save(provider, serializeCache);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,6 +454,17 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
return result;
|
||||
}
|
||||
|
||||
private bool TryCacheRemoveContext(string name)
|
||||
{
|
||||
bool result = Contexts.Remove(name);
|
||||
if (string.Equals(name, DefaultContextKey))
|
||||
{
|
||||
DefaultContextKey = Contexts.Keys.Any() ? null : "Default";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool TryRenameContext(string sourceName, string targetName)
|
||||
{
|
||||
bool result = false;
|
||||
|
@ -559,7 +594,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
{
|
||||
bool result = false;
|
||||
environment = null;
|
||||
if (HasEnvironment(name))
|
||||
if (name != null && HasEnvironment(name))
|
||||
{
|
||||
environment = EnvironmentTable[name];
|
||||
result = true;
|
||||
|
@ -631,5 +666,164 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Models
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void WriteWarningMessage(string message)
|
||||
{
|
||||
EventHandler<StreamEventArgs> writeWarningEvent;
|
||||
if (AzureSession.Instance.TryGetComponent(AzureRMCmdlet.WriteWarningKey, out writeWarningEvent))
|
||||
{
|
||||
writeWarningEvent(this, new StreamEventArgs() { Message = message });
|
||||
}
|
||||
}
|
||||
|
||||
private void EnqueueDebugMessage(string message)
|
||||
{
|
||||
EventHandler<StreamEventArgs> enqueueDebugEvent;
|
||||
if(AzureSession.Instance.TryGetComponent(AzureRMCmdlet.EnqueueDebugKey, out enqueueDebugEvent))
|
||||
{
|
||||
enqueueDebugEvent(this, new StreamEventArgs() { Message = message });
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshContextsFromCache()
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
authority = $"{sessionEnvironment.ActiveDirectoryAuthority}organizations";
|
||||
}
|
||||
var accounts = authenticationClientFactory.ListAccounts(authority);
|
||||
if (!accounts.Any())
|
||||
{
|
||||
if (!Contexts.Any(c => c.Key != "Default" && c.Value.Account.Type == AzureAccount.AccountType.User))
|
||||
{
|
||||
// If there are no accounts in the cache, but we never had any existing contexts, return
|
||||
return;
|
||||
}
|
||||
|
||||
WriteWarningMessage($"No accounts found in the shared token cache; removing all user contexts.");
|
||||
var removedContext = false;
|
||||
foreach (var contextName in Contexts.Keys)
|
||||
{
|
||||
var context = Contexts[contextName];
|
||||
if (context.Account.Type != AzureAccount.AccountType.User)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
removedContext |= TryCacheRemoveContext(contextName);
|
||||
}
|
||||
|
||||
// If no contexts were removed, return now to avoid writing to file later
|
||||
if (!removedContext)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var removedUsers = new HashSet<string>();
|
||||
var updatedContext = false;
|
||||
foreach (var contextName in Contexts.Keys)
|
||||
{
|
||||
var context = Contexts[contextName];
|
||||
if ((string.Equals(contextName, "Default") && context.Account == null) || context.Account.Type != AzureAccount.AccountType.User)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (accounts.Any(a => string.Equals(a.Username, context.Account.Id, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!removedUsers.Contains(context.Account.Id))
|
||||
{
|
||||
removedUsers.Add(context.Account.Id);
|
||||
WriteWarningMessage(string.Format(Resources.UserMissingFromSharedTokenCache, context.Account.Id));
|
||||
}
|
||||
|
||||
updatedContext |= TryCacheRemoveContext(contextName);
|
||||
}
|
||||
|
||||
// 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)
|
||||
.Any(v => string.Equals(v.Account.Id, account.Username, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
WriteWarningMessage(string.Format(Resources.CreatingContextsWarning, account.Username));
|
||||
var environment = sessionEnvironment ?? AzureEnvironment.PublicEnvironments
|
||||
.Where(env => env.Value.ActiveDirectoryAuthority.Contains(account.Environment))
|
||||
.Select(env => env.Value)
|
||||
.FirstOrDefault();
|
||||
var azureAccount = new AzureAccount()
|
||||
{
|
||||
Id = account.Username,
|
||||
Type = AzureAccount.AccountType.User
|
||||
};
|
||||
|
||||
List<IAccessToken> 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));
|
||||
EnqueueDebugMessage(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, WriteWarningMessage);
|
||||
if (!subscriptions.Any())
|
||||
{
|
||||
subscriptions.Add(null);
|
||||
}
|
||||
|
||||
foreach (var subscription in subscriptions)
|
||||
{
|
||||
var context = new AzureContext(subscription, azureAccount, environment, azureTenant);
|
||||
if (!TryGetContextName(context, out string name))
|
||||
{
|
||||
WriteWarningMessage(string.Format(Resources.NoContextNameForSubscription, subscription.Id));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!TrySetContext(name, context))
|
||||
{
|
||||
WriteWarningMessage(string.Format(Resources.UnableToCreateContextForSubscription, subscription.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
updatedContext = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the context list was not updated, return now to avoid writing to file later
|
||||
if (!updatedContext)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Save(ProfilePath, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,8 @@
|
|||
|
||||
using Microsoft.Azure.Commands.Common.Authentication;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
#if NETSTANDARD
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Core;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
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;
|
||||
|
@ -45,8 +43,6 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
|| objectType == typeof(IAzureTenant)
|
||||
|| objectType == typeof(IAzureTokenCache)
|
||||
|| objectType == typeof(AzureTokenCache)
|
||||
|| objectType == typeof(ProtectedFileTokenCache)
|
||||
|| objectType == typeof(AuthenticationStoreTokenCache)
|
||||
|| objectType == typeof(IAzureContextContainer);
|
||||
}
|
||||
|
||||
|
@ -79,13 +75,17 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
else if (objectType == typeof(IAzureTokenCache))
|
||||
{
|
||||
var tempResult = serializer.Deserialize<CacheBuffer>(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))
|
||||
{
|
||||
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<string, IAzureEnvironment>))
|
||||
{
|
||||
|
@ -120,7 +120,14 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
{
|
||||
if (_serializeCache)
|
||||
{
|
||||
value = new CacheBuffer { CacheData = cache.CacheData };
|
||||
byte[] cacheData = null;
|
||||
if (AzureSession.Instance.TryGetComponent(
|
||||
AuthenticationClientFactory.AuthenticationClientFactoryKey,
|
||||
out AuthenticationClientFactory authenticationClientFactory))
|
||||
{
|
||||
cacheData = authenticationClientFactory.ReadTokenData();
|
||||
}
|
||||
value = new CacheBuffer { CacheData = cacheData };
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -102,7 +102,6 @@ namespace Microsoft.Azure.Commands.Common.Authentication.ResourceManager
|
|||
context.Tenant = new AzureTenant();
|
||||
context.Tenant.CopyFrom(other.Tenant);
|
||||
context.CopyPropertiesFrom(other);
|
||||
context.TokenCache = AzureSession.Instance.TokenCache;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ namespace Microsoft.Azure.Commands.Profile.Models
|
|||
context.Tenant);
|
||||
}
|
||||
|
||||
result.TokenCache = context.TokenCache;
|
||||
result.TokenCache = null;
|
||||
result.VersionProfile = context.VersionProfile;
|
||||
result.CopyPropertiesFrom(context);
|
||||
return result;
|
||||
|
@ -103,7 +100,7 @@ namespace Microsoft.Azure.Commands.Profile.Models
|
|||
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 @@ namespace Microsoft.Azure.Commands.Profile.Models
|
|||
{
|
||||
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<string>(nameof(VersionProfile));
|
||||
this.PopulateExtensions(other);
|
||||
|
@ -176,7 +167,11 @@ namespace Microsoft.Azure.Commands.Profile.Models
|
|||
[Ps1Xml(Label = "TenantId", Target = ViewControl.Table, ScriptBlock = "$_.Tenant.ToString()", Position = 4)]
|
||||
public IAzureTenant Tenant { get; set; }
|
||||
|
||||
public IAzureTokenCache TokenCache { get; set; }
|
||||
/// <summary>
|
||||
/// Moved to <see cref="IClientApplicationBase.ClientTokenCache"> due to MSAL.
|
||||
/// See <see cref="AuthenticationClientFactory"> for how to create client applications.
|
||||
/// </summary>
|
||||
public IAzureTokenCache TokenCache { get; set; } = null;
|
||||
|
||||
public string VersionProfile { get; set; }
|
||||
|
||||
|
|
|
@ -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", "4.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 {
|
||||
|
@ -70,6 +70,24 @@ namespace Microsoft.Azure.Commands.Common.Authentication.ResourceManager.Propert
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Creating context for each subscription accessible by account '{0}'..
|
||||
/// </summary>
|
||||
internal static string CreatingContextsWarning {
|
||||
get {
|
||||
return ResourceManager.GetString("CreatingContextsWarning", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The default context can no longer be found; please run 'Get-AzContext -ListAvailable' to see all available contexts, 'Select-AzContext' to select a new default context, or 'Connect-AzAccount' to login with a new account..
|
||||
/// </summary>
|
||||
internal static string DefaultContextMissing {
|
||||
get {
|
||||
return ResourceManager.GetString("DefaultContextMissing", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Could not acquire access to file '{0}' please try again in a few minutes..
|
||||
/// </summary>
|
||||
|
@ -115,6 +133,15 @@ namespace Microsoft.Azure.Commands.Common.Authentication.ResourceManager.Propert
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to get context name for subscription with ID '{0}'..
|
||||
/// </summary>
|
||||
internal static string NoContextNameForSubscription {
|
||||
get {
|
||||
return ResourceManager.GetString("NoContextNameForSubscription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Please connect to internet before executing this cmdlet.
|
||||
/// </summary>
|
||||
|
@ -124,6 +151,15 @@ namespace Microsoft.Azure.Commands.Common.Authentication.ResourceManager.Propert
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to get token for account '{0}', please run Connect-AzAccount to login for {0} if you need to use this account..
|
||||
/// </summary>
|
||||
internal static string NoTokenFoundWarning {
|
||||
get {
|
||||
return ResourceManager.GetString("NoTokenFoundWarning", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A valid implementation of IDataStore must be provided..
|
||||
/// </summary>
|
||||
|
@ -241,6 +277,15 @@ namespace Microsoft.Azure.Commands.Common.Authentication.ResourceManager.Propert
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unable to create a context for subscription with ID '{0}..
|
||||
/// </summary>
|
||||
internal static string UnableToCreateContextForSubscription {
|
||||
get {
|
||||
return ResourceManager.GetString("UnableToCreateContextForSubscription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cannot read the file at '{0}'. Please ensure that you have appropriate access to this file and try executing this cmdlet again in a few minutes..
|
||||
/// </summary>
|
||||
|
@ -258,5 +303,14 @@ namespace Microsoft.Azure.Commands.Common.Authentication.ResourceManager.Propert
|
|||
return ResourceManager.GetString("UnwritableStream", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to User '{0}' was not found in the shared token cache; removing all contexts with this user..
|
||||
/// </summary>
|
||||
internal static string UserMissingFromSharedTokenCache {
|
||||
get {
|
||||
return ResourceManager.GetString("UserMissingFromSharedTokenCache", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,6 +120,12 @@
|
|||
<data name="CertificateNotFoundInStore" xml:space="preserve">
|
||||
<value>No certificate was found in the certificate store with thumbprint {0}</value>
|
||||
</data>
|
||||
<data name="CreatingContextsWarning" xml:space="preserve">
|
||||
<value>Creating context for each subscription accessible by account '{0}'.</value>
|
||||
</data>
|
||||
<data name="DefaultContextMissing" xml:space="preserve">
|
||||
<value>The default context can no longer be found; please run 'Get-AzContext -ListAvailable' to see all available contexts, 'Select-AzContext' to select a new default context, or 'Connect-AzAccount' to login with a new account.</value>
|
||||
</data>
|
||||
<data name="FileLockFailure" xml:space="preserve">
|
||||
<value>Could not acquire access to file '{0}' please try again in a few minutes.</value>
|
||||
<comment>{0} is the file path</comment>
|
||||
|
@ -136,9 +142,15 @@
|
|||
<data name="InvalidFilePath" xml:space="preserve">
|
||||
<value>A valid file path must be provided.</value>
|
||||
</data>
|
||||
<data name="NoContextNameForSubscription" xml:space="preserve">
|
||||
<value>Unable to get context name for subscription with ID '{0}'.</value>
|
||||
</data>
|
||||
<data name="NoInternetConnection" xml:space="preserve">
|
||||
<value>Please connect to internet before executing this cmdlet</value>
|
||||
</data>
|
||||
<data name="NoTokenFoundWarning" xml:space="preserve">
|
||||
<value>Failed to get token for account '{0}', please run Connect-AzAccount to login for {0} if you need to use this account.</value>
|
||||
</data>
|
||||
<data name="NullDataStore" xml:space="preserve">
|
||||
<value>A valid implementation of IDataStore must be provided.</value>
|
||||
</data>
|
||||
|
@ -178,6 +190,9 @@
|
|||
<data name="SessionNotInitialized" xml:space="preserve">
|
||||
<value>The Azure PowerShell session has not been properly initialized. Please import the module and try again.</value>
|
||||
</data>
|
||||
<data name="UnableToCreateContextForSubscription" xml:space="preserve">
|
||||
<value>Unable to create a context for subscription with ID '{0}.</value>
|
||||
</data>
|
||||
<data name="UnreadableStream" xml:space="preserve">
|
||||
<value>Cannot read the file at '{0}'. Please ensure that you have appropriate access to this file and try executing this cmdlet again in a few minutes.</value>
|
||||
<comment>{0} is the file path</comment>
|
||||
|
@ -186,4 +201,7 @@
|
|||
<value>Cannot write to the file at '{0}'. Please ensure that you have appropriate access to this file and try executing this cmdlet again in a few minutes.</value>
|
||||
<comment>{0} is the file path</comment>
|
||||
</data>
|
||||
<data name="UserMissingFromSharedTokenCache" xml:space="preserve">
|
||||
<value>User '{0}' was not found in the shared token cache; removing all contexts with this user.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -14,20 +14,17 @@
|
|||
|
||||
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.IdentityModel.Clients.ActiveDirectory;
|
||||
using Microsoft.Identity.Client;
|
||||
using System.IO;
|
||||
|
||||
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 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common
|
|||
}
|
||||
}
|
||||
|
||||
public override void ResetDefaultProfile()
|
||||
{
|
||||
foreach (var context in _profile.Contexts.Values)
|
||||
{
|
||||
context.TokenCache.Clear();
|
||||
}
|
||||
|
||||
base.ResetDefaultProfile();
|
||||
}
|
||||
|
||||
public override T GetProfile<T>()
|
||||
{
|
||||
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.Deserialize(profile.GetTokenCache().CacheData);
|
||||
}
|
||||
|
||||
profile.SetTokenCache(cache);
|
||||
}
|
||||
|
||||
|
||||
public override IAzureContextContainer Profile
|
||||
{
|
||||
get
|
||||
|
|
|
@ -14,42 +14,17 @@
|
|||
|
||||
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.IdentityModel.Clients.ActiveDirectory;
|
||||
using Microsoft.Identity.Client;
|
||||
|
||||
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(TokenCache.DefaultShared);
|
||||
if (profile.HasTokenCache())
|
||||
{
|
||||
cache.Deserialize(profile.GetTokenCache().CacheData);
|
||||
}
|
||||
|
||||
AzureSession.Instance.TokenCache = cache;
|
||||
profile.SetTokenCache(cache);
|
||||
}
|
||||
|
||||
AzureRmProfile _profile = new AzureRmProfile { DefaultContext = new AzureContext() };
|
||||
|
||||
public override T GetProfile<T>()
|
||||
{
|
||||
return Profile as T;
|
||||
|
|
|
@ -46,13 +46,7 @@ namespace Microsoft.Azure.Commands.ResourceManager.Common.Serialization
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)..\..\Az.Test.props" />
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\Authentication.ResourceManager\Authentication.ResourceManager.csproj" />
|
||||
<ProjectReference Include="..\Authentication\Authentication.csproj" />
|
||||
<ProjectReference Include="..\Authenticators\Authenticators.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -24,6 +24,8 @@ using System.Linq;
|
|||
using Microsoft.Azure.Commands.Common.Authentication.Test;
|
||||
using Microsoft.WindowsAzure.Commands.Utilities.Common;
|
||||
using Xunit.Abstractions;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
using Microsoft.Azure.PowerShell.Authenticators;
|
||||
|
||||
namespace Common.Authentication.Test
|
||||
{
|
||||
|
@ -35,7 +37,7 @@ namespace Common.Authentication.Test
|
|||
_output = output;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact(Skip = "Need to determine how to adapt this test to new shared token cache model.")]
|
||||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void VerifySubscriptionTokenCacheRemove()
|
||||
{
|
||||
|
@ -115,6 +117,10 @@ namespace Common.Authentication.Test
|
|||
public void CanAuthenticateWithAccessToken()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAuthenticatorBuilder authenticatorBuilder = new DefaultAuthenticatorBuilder();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => authenticatorBuilder);
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
string tenant = Guid.NewGuid().ToString();
|
||||
string userId = "user1@contoso.org";
|
||||
var armToken = Guid.NewGuid().ToString();
|
||||
|
@ -150,6 +156,10 @@ namespace Common.Authentication.Test
|
|||
public void CanAuthenticateUsingMSIDefault()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAuthenticatorBuilder authenticatorBuilder = new DefaultAuthenticatorBuilder();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => authenticatorBuilder);
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
string expectedAccessToken = Guid.NewGuid().ToString();
|
||||
_output.WriteLine("Expected access token for default URI: {0}", expectedAccessToken);
|
||||
string expectedToken2 = Guid.NewGuid().ToString();
|
||||
|
@ -196,6 +206,10 @@ namespace Common.Authentication.Test
|
|||
public void CanAuthenticateUsingMSIResourceId()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAuthenticatorBuilder authenticatorBuilder = new DefaultAuthenticatorBuilder();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => authenticatorBuilder);
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
string expectedAccessToken = Guid.NewGuid().ToString();
|
||||
_output.WriteLine("Expected access token for ARM URI: {0}", expectedAccessToken);
|
||||
string expectedToken2 = Guid.NewGuid().ToString();
|
||||
|
@ -245,6 +259,10 @@ namespace Common.Authentication.Test
|
|||
public void CanAuthenticateUsingMSIClientId()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAuthenticatorBuilder authenticatorBuilder = new DefaultAuthenticatorBuilder();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => authenticatorBuilder);
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
string expectedAccessToken = Guid.NewGuid().ToString();
|
||||
_output.WriteLine("Expected access token for ARM URI: {0}", expectedAccessToken);
|
||||
string expectedToken2 = Guid.NewGuid().ToString();
|
||||
|
@ -294,6 +312,10 @@ namespace Common.Authentication.Test
|
|||
public void CanAuthenticateUsingMSIObjectId()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAuthenticatorBuilder authenticatorBuilder = new DefaultAuthenticatorBuilder();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => authenticatorBuilder);
|
||||
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
|
||||
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
|
||||
string expectedAccessToken = Guid.NewGuid().ToString();
|
||||
_output.WriteLine("Expected access token for ARM URI: {0}", expectedAccessToken);
|
||||
string expectedToken2 = Guid.NewGuid().ToString();
|
||||
|
|
|
@ -1,90 +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
|
||||
{
|
||||
[Fact]
|
||||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void InitializerCreatesTokenCacheFile()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAzureSession oldSession = null;
|
||||
try
|
||||
{
|
||||
oldSession = AzureSession.Instance;
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
var store = new MemoryDataStore();
|
||||
var path = Path.Combine(AzureSession.Instance.ARMProfileDirectory, ContextAutosaveSettings.AutoSaveSettingsFile);
|
||||
var settings = new ContextAutosaveSettings {Mode=ContextSaveMode.CurrentUser };
|
||||
var content = JsonConvert.SerializeObject(settings);
|
||||
store.VirtualStore[path] = content;
|
||||
AzureSessionInitializer.CreateOrReplaceSession(store);
|
||||
var session = AzureSession.Instance;
|
||||
var tokenCacheFile = Path.Combine(session.ProfileDirectory, session.TokenCacheFile);
|
||||
Assert.True(store.FileExists(tokenCacheFile));
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
AzureSession.Initialize(() => oldSession, true);
|
||||
}
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ namespace Common.Authentication.Test
|
|||
Assert.Contains(factory.UserAgents, u => u.Product.Name == "test3" && u.Product.Version == null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact(Skip = "Need to determine a way to populate the cache with the given dummy account.")]
|
||||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void VerifyUserAgentValuesAreTransmitted()
|
||||
{
|
||||
|
|
|
@ -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 @@ namespace Common.Authentication.Test.Cmdlets
|
|||
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 @@ namespace Common.Authentication.Test.Cmdlets
|
|||
}
|
||||
}
|
||||
|
||||
_profile.DefaultContext.TokenCache = _cache;
|
||||
var defaultContext = _profile.DefaultContext;
|
||||
var subscriptions = ListSubscriptions(tenantId).Take(25);
|
||||
foreach (var subscription in subscriptions)
|
||||
|
@ -293,7 +285,6 @@ namespace Common.Authentication.Test.Cmdlets
|
|||
};
|
||||
|
||||
var tempContext = new AzureContext(subscription, account, environment, tempTenant);
|
||||
tempContext.TokenCache = _cache;
|
||||
string tempName = null;
|
||||
if (!_profile.TryGetContextName(tempContext, out tempName))
|
||||
{
|
||||
|
@ -408,7 +399,7 @@ namespace Common.Authentication.Test.Cmdlets
|
|||
password,
|
||||
promptBehavior,
|
||||
promptAction,
|
||||
_cache);
|
||||
null);
|
||||
}
|
||||
|
||||
private IEnumerable<IAzureSubscription> ListSubscriptions(string tenantIdOrDomain = "")
|
||||
|
|
|
@ -27,10 +27,7 @@ namespace Common.Authentication.Test
|
|||
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)]
|
||||
|
|
|
@ -17,13 +17,11 @@ using Common.Authentication.Test.Cmdlets;
|
|||
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;
|
||||
using Microsoft.Azure.Internal.Subscriptions.Models;
|
||||
using Microsoft.Identity.Client;
|
||||
using Microsoft.Rest;
|
||||
using Microsoft.WindowsAzure.Commands.Common.Test.Mocks;
|
||||
using Microsoft.WindowsAzure.Commands.ScenarioTest;
|
||||
|
@ -96,7 +94,7 @@ namespace Common.Authentication.Test
|
|||
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 };
|
||||
|
@ -141,30 +139,9 @@ namespace Common.Authentication.Test
|
|||
|
||||
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 && memoryCache.Count > 0)
|
||||
{
|
||||
diskCache.Deserialize(memoryCache.Serialize());
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -23,15 +23,18 @@ using System.Globalization;
|
|||
using System.Management.Automation;
|
||||
using Xunit;
|
||||
using System.Linq;
|
||||
using Microsoft.Azure.Commands.Common.Authentication;
|
||||
|
||||
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]
|
||||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void CanConvertFullProfilet()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
var context = GetDefaultContext();
|
||||
var prof = new PSAzureProfile();
|
||||
prof.Context = new PSAzureContext(context);
|
||||
|
@ -46,6 +49,7 @@ namespace Common.Authentication.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void CanConvertProfileNullComponent()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
var context = GetDefaultContext();
|
||||
context.Subscription = null;
|
||||
var prof = new PSAzureProfile();
|
||||
|
@ -61,6 +65,7 @@ namespace Common.Authentication.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void CanConvertProfieWithCustomEnvironment()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAzureContext context = new AzureContext(new AzureSubscription(), new AzureAccount(), new AzureEnvironment(), new AzureTenant(), new byte[0]);
|
||||
var testContext = new PSAzureContext(context);
|
||||
var testEnvironment = new PSAzureEnvironment(AzureEnvironment.PublicEnvironments["AzureCloud"]);
|
||||
|
@ -89,6 +94,7 @@ namespace Common.Authentication.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void ConConvertEmptyProfile()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
ConvertAndTestProfile(new PSAzureProfile(), (profile) =>
|
||||
{
|
||||
AssertStandardEnvironments(profile);
|
||||
|
@ -100,6 +106,7 @@ namespace Common.Authentication.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void CanConvertFullContext()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
var context = GetDefaultContext();
|
||||
ConvertAndTestProfile(context, (profile) =>
|
||||
{
|
||||
|
@ -112,6 +119,7 @@ namespace Common.Authentication.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void CanConvertContextNullComponent()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
var context = GetDefaultContext();
|
||||
context.Subscription = null;
|
||||
ConvertAndTestProfile(context, (profile) =>
|
||||
|
@ -125,6 +133,7 @@ namespace Common.Authentication.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void CanConvertMinimalContext()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
IAzureContext context = new AzureContext(new AzureSubscription(), new AzureAccount(), new AzureEnvironment(), new AzureTenant(), new byte[0]);
|
||||
ConvertAndTestProfile(new PSAzureContext(context), (profile) =>
|
||||
{
|
||||
|
@ -138,6 +147,7 @@ namespace Common.Authentication.Test
|
|||
[Trait(Category.AcceptanceType, Category.CheckIn)]
|
||||
public void CanConvertEmptyContext()
|
||||
{
|
||||
AzureSessionInitializer.InitializeAzureSession();
|
||||
ConvertAndTestProfile(new PSAzureContext(), (profile) =>
|
||||
{
|
||||
AssertStandardEnvironments(profile);
|
||||
|
@ -225,20 +235,6 @@ namespace Common.Authentication.Test
|
|||
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
|
||||
|
@ -247,7 +243,7 @@ namespace Common.Authentication.Test
|
|||
Environment = GetDefaultEnvironment(),
|
||||
Subscription = GetDefaultSubscription(),
|
||||
Tenant = GetDefaultTenant(),
|
||||
TokenCache = GetDefaultTokenCache(),
|
||||
TokenCache = null,
|
||||
VersionProfile = "2017_09_25"
|
||||
};
|
||||
|
||||
|
|
|
@ -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 @@ namespace Common.Authentication.Test
|
|||
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 @@ namespace Common.Authentication.Test
|
|||
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<string>(), It.IsAny<string>()), Times.Once);
|
||||
|
@ -103,8 +100,6 @@ namespace Common.Authentication.Test
|
|||
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<string>()), Times.AtLeastOnce);
|
||||
|
@ -127,8 +122,6 @@ namespace Common.Authentication.Test
|
|||
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<string>()), Times.AtLeastOnce);
|
||||
|
@ -152,8 +145,6 @@ namespace Common.Authentication.Test
|
|||
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<string>()), Times.AtLeastOnce);
|
||||
|
@ -178,8 +169,6 @@ namespace Common.Authentication.Test
|
|||
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<string>()), Times.AtLeastOnce());
|
||||
|
@ -205,8 +194,6 @@ namespace Common.Authentication.Test
|
|||
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<string>(), It.IsAny<string>()), Times.AtLeastOnce);
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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 System;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings for authentication with an Azure or Azure Stack service using Active Directory.
|
||||
/// </summary>
|
||||
public sealed class ActiveDirectoryServiceSettings
|
||||
{
|
||||
private Uri _authenticationEndpoint;
|
||||
|
||||
private static readonly ActiveDirectoryServiceSettings AzureSettings = new ActiveDirectoryServiceSettings
|
||||
{
|
||||
AuthenticationEndpoint = new Uri("https://login.microsoftonline.com/"),
|
||||
TokenAudience = new Uri("https://management.core.windows.net/"),
|
||||
ValidateAuthority = true
|
||||
};
|
||||
|
||||
private static readonly ActiveDirectoryServiceSettings AzureChinaSettings = new ActiveDirectoryServiceSettings
|
||||
{
|
||||
AuthenticationEndpoint = new Uri("https://login.chinacloudapi.cn/"),
|
||||
TokenAudience = new Uri("https://management.core.chinacloudapi.cn/"),
|
||||
ValidateAuthority = true
|
||||
};
|
||||
|
||||
private static readonly ActiveDirectoryServiceSettings AzureUSGovernmentSettings = new ActiveDirectoryServiceSettings
|
||||
{
|
||||
AuthenticationEndpoint = new Uri("https://login.microsoftonline.us/"),
|
||||
TokenAudience = new Uri("https://management.core.usgovcloudapi.net/"),
|
||||
ValidateAuthority = true
|
||||
};
|
||||
|
||||
private static readonly ActiveDirectoryServiceSettings AzureGermanCloudSettings = new ActiveDirectoryServiceSettings
|
||||
{
|
||||
AuthenticationEndpoint = new Uri("https://login.microsoftonline.de/"),
|
||||
TokenAudience = new Uri("https://management.core.cloudapi.de/"),
|
||||
ValidateAuthority = true
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the serviceSettings for authentication with Azure
|
||||
/// </summary>
|
||||
public static ActiveDirectoryServiceSettings Azure { get { return AzureSettings; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the serviceSettings for authentication with Azure China
|
||||
/// </summary>
|
||||
public static ActiveDirectoryServiceSettings AzureChina { get { return AzureChinaSettings; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the serviceSettings for authentication with Azure US Government
|
||||
/// </summary>
|
||||
public static ActiveDirectoryServiceSettings AzureUSGovernment { get { return AzureUSGovernmentSettings; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the serviceSettings for authentication with Azure Germany
|
||||
/// </summary>
|
||||
public static ActiveDirectoryServiceSettings AzureGermany { get { return AzureGermanCloudSettings; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ActiveDirectory Endpoint for the Azure Environment
|
||||
/// </summary>
|
||||
public Uri AuthenticationEndpoint
|
||||
{
|
||||
get { return _authenticationEndpoint; }
|
||||
set { _authenticationEndpoint = EnsureTrailingSlash(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Token audience for an endpoint
|
||||
/// </summary>
|
||||
public Uri TokenAudience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether the authentication endpoint should be validated with Azure AD
|
||||
/// </summary>
|
||||
public bool ValidateAuthority { get; set; }
|
||||
|
||||
private static Uri EnsureTrailingSlash(Uri authenticationEndpoint)
|
||||
{
|
||||
if (authenticationEndpoint == null)
|
||||
{
|
||||
throw new ArgumentNullException("authenticationEndpoint");
|
||||
}
|
||||
|
||||
UriBuilder builder = new UriBuilder(authenticationEndpoint);
|
||||
if (!string.IsNullOrEmpty(builder.Query))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(authenticationEndpoint), "The authentication endpoint must not contain a query string.");
|
||||
}
|
||||
|
||||
var path = builder.Path;
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
path = "/";
|
||||
}
|
||||
else if (!path.EndsWith("/", StringComparison.Ordinal))
|
||||
{
|
||||
path = path + "/";
|
||||
}
|
||||
|
||||
builder.Path = path;
|
||||
return builder.Uri;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,144 +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.IdentityModel.Clients.ActiveDirectory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements logging callback for ADAL - since only a single logger is allowed, allow
|
||||
/// reporting logs to multiple logging mechanisms
|
||||
/// </summary>
|
||||
public class AdalLogger : IDisposable
|
||||
{
|
||||
Action<string> _logger;
|
||||
|
||||
public AdalLogger(Action<string> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
AdalCompositeLogger.Enable(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually disable the logger
|
||||
/// </summary>
|
||||
public static void Disable()
|
||||
{
|
||||
AdalCompositeLogger.Disable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free resources associated with a logger and disable it
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove this logger from the logging delegate
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
public virtual void Dispose( bool disposing)
|
||||
{
|
||||
if (disposing && _logger != null)
|
||||
{
|
||||
AdalCompositeLogger.Disable(this);
|
||||
_logger = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle the given ADAL log message
|
||||
/// </summary>
|
||||
/// <param name="level">The log level</param>
|
||||
/// <param name="message">The log message</param>
|
||||
public void Log(LogLevel level, string message)
|
||||
{
|
||||
_logger($"[ADAL]: {level}: {message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Central logging mechanism - allows registering multiple logging callbacks
|
||||
/// </summary>
|
||||
class AdalCompositeLogger
|
||||
{
|
||||
static object _lockObject = new object();
|
||||
IList<AdalLogger> _loggers = new List<AdalLogger>();
|
||||
private AdalCompositeLogger()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// singleton logger instance, since only one log callback delegate is allowed
|
||||
/// </summary>
|
||||
static AdalCompositeLogger Instance { get; } = new AdalCompositeLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Enable logging through the given logging delegate
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger to send ADAL messages to</param>
|
||||
internal static void Enable(AdalLogger logger)
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
Instance._loggers.Add(logger);
|
||||
LoggerCallbackHandler.LogCallback = Instance.Log;
|
||||
LoggerCallbackHandler.PiiLoggingEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable all ADAL logging
|
||||
/// </summary>
|
||||
internal static void Disable()
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
Instance._loggers.Clear();
|
||||
LoggerCallbackHandler.UseDefaultLogging = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable the given logger by removing from the logger collection
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
internal static void Disable(AdalLogger logger)
|
||||
{
|
||||
lock (_lockObject)
|
||||
{
|
||||
Instance._loggers.Remove(logger);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message to all active loggers
|
||||
/// </summary>
|
||||
/// <param name="level">The log level</param>
|
||||
/// <param name="message">The log message</param>
|
||||
public void Log(LogLevel level, string message, bool containsPII)
|
||||
{
|
||||
foreach (var logger in _loggers)
|
||||
{
|
||||
logger.Log(level, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
using System;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Identity.Client;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Rest;
|
||||
using System.Security;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Properties;
|
||||
|
||||
/// <summary>
|
||||
/// Provides tokens for Azure Active Directory applications.
|
||||
/// </summary>
|
||||
public class ApplicationTokenProvider : Microsoft.Rest.ITokenProvider
|
||||
{
|
||||
#region fields
|
||||
private IPublicClientApplication _publicClient;
|
||||
private string _tokenAudience;
|
||||
private IApplicationAuthenticationProvider _authentications;
|
||||
private string _clientId;
|
||||
private DateTimeOffset _expiration;
|
||||
private string _accessToken;
|
||||
private static readonly TimeSpan ExpirationThreshold = TimeSpan.FromMinutes(5);
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
/// <summary>
|
||||
/// Create an application token provider that can retrieve tokens for the given application from the given context, using the given audience
|
||||
/// and credential store.
|
||||
/// See <see href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-devquickstarts-dotnet/">Active Directory Quickstart for .Net</see>
|
||||
/// for detailed instructions on creating an Azure Active Directory application.
|
||||
/// </summary>
|
||||
/// <param name="context">The authentication context to use when retrieving tokens.</param>
|
||||
/// <param name="tokenAudience">The token audience to use when retrieving tokens</param>
|
||||
/// <param name="clientId">The client Id for this active directory application</param>
|
||||
/// <param name="authenticationStore">The source of authentication information for this application.</param>
|
||||
/// <param name="authenticationResult">The authenticationResult of initial authentication with the application credentials.</param>
|
||||
public ApplicationTokenProvider(IPublicClientApplication context, string tokenAudience, string clientId,
|
||||
IApplicationAuthenticationProvider authenticationStore, AuthenticationResult authenticationResult)
|
||||
{
|
||||
if (authenticationResult == null)
|
||||
{
|
||||
throw new ArgumentNullException("authenticationResult");
|
||||
}
|
||||
|
||||
Initialize(context, tokenAudience, clientId, authenticationStore, authenticationResult, authenticationResult.ExpiresOn);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates ServiceClientCredentials for authenticating requests as an active directory application.
|
||||
/// See <see href="https://azure.microsoft.com/en-us/documentation/articles/active-directory-devquickstarts-dotnet/">Active Directory Quickstart for .Net</see>
|
||||
/// for detailed instructions on creating an Azure Active Directory application.
|
||||
/// </summary>
|
||||
/// <param name="domain">The active directory domain or tenantId to authenticate with.</param>
|
||||
/// <param name="clientId">The active directory clientId for the application.</param>
|
||||
/// <param name="authenticationProvider">A source for the secure secret for this application.</param>
|
||||
/// <param name="settings">The active directory service side settings, including authority and token audience.</param>
|
||||
/// <param name="cache">The token cache to target during authentication.</param>
|
||||
/// <returns>A ServiceClientCredentials object that can authenticate http requests as the given application.</returns>
|
||||
public static async Task<ServiceClientCredentials> LoginSilentAsync(string domain, string clientId,
|
||||
IApplicationAuthenticationProvider authenticationProvider, ActiveDirectoryServiceSettings settings, TokenCache cache)
|
||||
{
|
||||
var authority = settings.AuthenticationEndpoint + domain;
|
||||
var audience = settings.TokenAudience.OriginalString;
|
||||
AuthenticationClientFactory authenticationClientFactory;
|
||||
if (!AzureSession.Instance.TryGetComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, out authenticationClientFactory))
|
||||
{
|
||||
throw new NullReferenceException(Resources.AuthenticationClientFactoryNotRegistered);
|
||||
}
|
||||
|
||||
var publicClient = authenticationClientFactory.CreatePublicClient(clientId: clientId, authority: authority);
|
||||
var authResult = await authenticationProvider.AuthenticateAsync(clientId, audience);
|
||||
return new TokenCredentials(
|
||||
new ApplicationTokenProvider(publicClient, audience, clientId, authenticationProvider, authResult),
|
||||
authResult.TenantId,
|
||||
authResult.Account == null ? null : authResult.Account.Username);
|
||||
}
|
||||
|
||||
protected virtual bool AccessTokenExpired
|
||||
{
|
||||
get { return DateTime.UtcNow + ExpirationThreshold >= this._expiration; }
|
||||
}
|
||||
|
||||
private void Initialize(IPublicClientApplication publicClient, string tokenAudience, string clientId,
|
||||
IApplicationAuthenticationProvider authenticationStore, AuthenticationResult authenticationResult, DateTimeOffset tokenExpiration)
|
||||
{
|
||||
if (publicClient == null)
|
||||
{
|
||||
throw new ArgumentNullException("publicClient");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tokenAudience))
|
||||
{
|
||||
throw new ArgumentNullException("tokenAudience");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(clientId))
|
||||
{
|
||||
throw new ArgumentNullException("clientId");
|
||||
}
|
||||
|
||||
if (authenticationStore == null)
|
||||
{
|
||||
throw new ArgumentNullException("authenticationStore");
|
||||
}
|
||||
if (authenticationResult == null)
|
||||
{
|
||||
throw new ArgumentNullException("authenticationResult");
|
||||
}
|
||||
|
||||
this._authentications = authenticationStore;
|
||||
this._clientId = clientId;
|
||||
this._publicClient = publicClient;
|
||||
this._accessToken = authenticationResult.AccessToken;
|
||||
this._tokenAudience = tokenAudience;
|
||||
this._expiration = tokenExpiration;
|
||||
}
|
||||
|
||||
public virtual async Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
AuthenticationResult result;
|
||||
if (AccessTokenExpired)
|
||||
{
|
||||
result = await this._authentications.AuthenticateAsync(this._clientId, this._tokenAudience).ConfigureAwait(false);
|
||||
this._accessToken = result.AccessToken;
|
||||
this._expiration = result.ExpiresOn;
|
||||
}
|
||||
|
||||
return new AuthenticationHeaderValue("Bearer", this._accessToken);
|
||||
}
|
||||
catch (MsalException authenticationException)
|
||||
{
|
||||
throw new MsalException(authenticationException.ErrorCode, "Authentication error while acquiring token.", authenticationException);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<PsModuleName>Accounts</PsModuleName>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<Import Project="$(MSBuildThisFileDirectory)..\..\Az.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
|
@ -12,7 +12,24 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.19.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Identity.Client" Version="4.8.1" />
|
||||
<PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="2.7.0-preview" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -12,7 +12,7 @@
|
|||
// limitations under the License.
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.IdentityModel.Clients.ActiveDirectory;
|
||||
using Microsoft.Identity.Client;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
|
|
|
@ -1,99 +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.IdentityModel.Clients.ActiveDirectory;
|
||||
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 : TokenCache, IAzureTokenCache, IDisposable
|
||||
{
|
||||
IAzureTokenCache _store = new AzureTokenCache();
|
||||
public byte[] CacheData
|
||||
{
|
||||
get
|
||||
{
|
||||
return Serialize();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.Deserialize(value);
|
||||
}
|
||||
}
|
||||
|
||||
public AuthenticationStoreTokenCache(AzureTokenCache store) : base()
|
||||
{
|
||||
if (null == store)
|
||||
{
|
||||
throw new ArgumentNullException("store");
|
||||
}
|
||||
|
||||
if (store.CacheData != null && store.CacheData.Length > 0)
|
||||
{
|
||||
CacheData = store.CacheData;
|
||||
}
|
||||
|
||||
AfterAccess += HandleAfterAccess;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a token cache, copying any data from the given token cache
|
||||
/// </summary>
|
||||
/// <param name="cache">The cache to copy</param>
|
||||
/// <param name="store">The store to use for persisting state</param>
|
||||
public AuthenticationStoreTokenCache(TokenCache cache) : base()
|
||||
{
|
||||
if (null == cache)
|
||||
{
|
||||
throw new ArgumentNullException("Cache");
|
||||
}
|
||||
|
||||
CacheData = cache.Serialize();
|
||||
AfterAccess += HandleAfterAccess;
|
||||
}
|
||||
|
||||
public void HandleAfterAccess(TokenCacheNotificationArgs args)
|
||||
{
|
||||
if (HasStateChanged)
|
||||
{
|
||||
_store.CacheData = Serialize();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
var cache = Interlocked.Exchange(ref _store, null);
|
||||
if (cache != null)
|
||||
{
|
||||
cache.CacheData = Serialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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 Hyak.Common;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
using Microsoft.Azure.Internal.Subscriptions;
|
||||
using Microsoft.Azure.Internal.Subscriptions.Models;
|
||||
using Microsoft.Identity.Client;
|
||||
using Microsoft.Rest;
|
||||
using Microsoft.WindowsAzure.Commands.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients
|
||||
{
|
||||
public abstract class AuthenticationClientFactory
|
||||
{
|
||||
public static readonly string AuthenticationClientFactoryKey = nameof(AuthenticationClientFactory);
|
||||
protected static readonly string PowerShellClientId = "1950a258-227b-4e31-a9cf-717495945fc2";
|
||||
private static readonly string CommonTenant = "organizations";
|
||||
|
||||
protected byte[] _tokenCacheDataToFlush;
|
||||
|
||||
protected AuthenticationClientFactory(string cacheFilePath = null)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract byte[] ReadTokenData();
|
||||
|
||||
public void UpdateTokenDataWithoutFlush(byte[] data)
|
||||
{
|
||||
_tokenCacheDataToFlush = data;
|
||||
}
|
||||
|
||||
public virtual void FlushTokenData()
|
||||
{
|
||||
_tokenCacheDataToFlush = null;
|
||||
}
|
||||
|
||||
public abstract void RegisterCache(IClientApplicationBase client);
|
||||
|
||||
public virtual void ClearCache()
|
||||
{
|
||||
}
|
||||
|
||||
public IPublicClientApplication CreatePublicClient(
|
||||
string clientId = null,
|
||||
string tenantId = null,
|
||||
string authority = null,
|
||||
string redirectUri = null,
|
||||
bool useAdfs = false)
|
||||
{
|
||||
clientId = clientId ?? PowerShellClientId;
|
||||
var builder = PublicClientApplicationBuilder.Create(clientId);
|
||||
if (!string.IsNullOrEmpty(authority))
|
||||
{
|
||||
if (!useAdfs)
|
||||
{
|
||||
builder = builder.WithAuthority(authority);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder = builder.WithAdfsAuthority(authority);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(tenantId))
|
||||
{
|
||||
builder = builder.WithTenantId(tenantId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(redirectUri))
|
||||
{
|
||||
builder = builder.WithRedirectUri(redirectUri);
|
||||
}
|
||||
|
||||
builder.WithLogging((level, message, pii) =>
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[MSAL] {0}: {1}", level, message));
|
||||
});
|
||||
|
||||
var client = builder.Build();
|
||||
RegisterCache(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
public IConfidentialClientApplication CreateConfidentialClient(
|
||||
string clientId = null,
|
||||
string authority = null,
|
||||
string redirectUri = null,
|
||||
X509Certificate2 certificate = null,
|
||||
SecureString clientSecret = null,
|
||||
bool useAdfs = false)
|
||||
{
|
||||
clientId = clientId ?? PowerShellClientId;
|
||||
var builder = ConfidentialClientApplicationBuilder.Create(clientId);
|
||||
if (!string.IsNullOrEmpty(authority))
|
||||
{
|
||||
if (!useAdfs)
|
||||
{
|
||||
builder = builder.WithAuthority(authority);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder = builder.WithAdfsAuthority(authority);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(redirectUri))
|
||||
{
|
||||
builder = builder.WithRedirectUri(redirectUri);
|
||||
}
|
||||
|
||||
if (certificate != null)
|
||||
{
|
||||
builder = builder.WithCertificate(certificate);
|
||||
}
|
||||
|
||||
if (clientSecret != null)
|
||||
{
|
||||
builder = builder.WithClientSecret(ConversionUtilities.SecureStringToString(clientSecret));
|
||||
}
|
||||
|
||||
builder.WithLogging((level, message, pii) =>
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[MSAL] {0}: {1}", level, message));
|
||||
});
|
||||
|
||||
var client = builder.Build();
|
||||
RegisterCache(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
public bool TryRemoveAccount(string accountId)
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[AuthenticationClientFactory] Calling GetAccountsAsync"));
|
||||
var client = CreatePublicClient();
|
||||
var account = client.GetAccountsAsync()
|
||||
.ConfigureAwait(false).GetAwaiter().GetResult()
|
||||
.FirstOrDefault(a => string.Equals(a.Username, accountId, StringComparison.OrdinalIgnoreCase));
|
||||
if (account == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[AuthenticationClientFactory] Calling RemoveAsync - Account: '{0}'", account.Username));
|
||||
client.RemoveAsync(account)
|
||||
.ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public IEnumerable<IAccount> ListAccounts(string authority = null)
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[AuthenticationClientFactory] Calling GetAccountsAsync on {0}", authority ?? "AzureCloud"));
|
||||
|
||||
return CreatePublicClient(authority: authority)
|
||||
.GetAccountsAsync()
|
||||
.ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public List<IAccessToken> GetTenantTokensForAccount(IAccount account, IAzureEnvironment environment, Action<string> promptAction)
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[AuthenticationClientFactory] Attempting to acquire tenant tokens for account '{0}'.", account.Username));
|
||||
List<IAccessToken> result = new List<IAccessToken>();
|
||||
var azureAccount = new AzureAccount()
|
||||
{
|
||||
Id = account.Username,
|
||||
Type = AzureAccount.AccountType.User
|
||||
};
|
||||
var commonToken = AzureSession.Instance.AuthenticationFactory.Authenticate(azureAccount, environment, CommonTenant, null, null, promptAction);
|
||||
IEnumerable<string> tenants = Enumerable.Empty<string>();
|
||||
using (SubscriptionClient subscriptionClient = GetSubscriptionClient(commonToken, environment))
|
||||
{
|
||||
tenants = subscriptionClient.Tenants.List().Select(t => t.TenantId);
|
||||
}
|
||||
|
||||
foreach (var tenant in tenants)
|
||||
{
|
||||
try
|
||||
{
|
||||
var token = AzureSession.Instance.AuthenticationFactory.Authenticate(azureAccount, environment, tenant, null, null, promptAction);
|
||||
if (token != null)
|
||||
{
|
||||
result.Add(token);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
promptAction($"Unable to acquire token for tenant '{tenant}'.");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<IAzureSubscription> GetSubscriptionsFromTenantToken(IAccount account, IAzureEnvironment environment, IAccessToken token, Action<string> promptAction)
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[AuthenticationClientFactory] Attempting to acquire subscriptions in tenant '{0}' for account '{1}'.", token.TenantId, account.Username));
|
||||
List<IAzureSubscription> result = new List<IAzureSubscription>();
|
||||
var azureAccount = new AzureAccount()
|
||||
{
|
||||
Id = account.Username,
|
||||
Type = AzureAccount.AccountType.User
|
||||
};
|
||||
using (SubscriptionClient subscriptionClient = GetSubscriptionClient(token, environment))
|
||||
{
|
||||
var subscriptions = (subscriptionClient.ListAllSubscriptions().ToList() ?? new List<Subscription>())
|
||||
.Where(s => "enabled".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase) ||
|
||||
"warned".Equals(s.State.ToString(), StringComparison.OrdinalIgnoreCase));
|
||||
foreach (var subscription in subscriptions)
|
||||
{
|
||||
var azureSubscription = new AzureSubscription();
|
||||
azureSubscription.SetAccount(azureAccount.Id);
|
||||
azureSubscription.SetEnvironment(environment.Name);
|
||||
azureSubscription.Id = subscription?.SubscriptionId;
|
||||
azureSubscription.Name = subscription?.DisplayName;
|
||||
azureSubscription.State = subscription?.State.ToString();
|
||||
azureSubscription.SetProperty(AzureSubscription.Property.Tenants, token.TenantId);
|
||||
result.Add(azureSubscription);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SubscriptionClient GetSubscriptionClient(IAccessToken token, IAzureEnvironment environment)
|
||||
{
|
||||
return AzureSession.Instance.ClientFactory.CreateCustomArmClient<SubscriptionClient>(
|
||||
environment.GetEndpointAsUri(AzureEnvironment.Endpoint.ResourceManager),
|
||||
new TokenCredentials(token.AccessToken) as ServiceClientCredentials,
|
||||
AzureSession.Instance.ClientFactory.GetCustomHandlers());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients
|
||||
{
|
||||
/// <summary>
|
||||
/// Serialization format of token cache.
|
||||
/// </summary>
|
||||
public enum CacheFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// Older Az.Accounts versions work with this format
|
||||
/// </summary>
|
||||
AdalV3,
|
||||
/// <summary>
|
||||
/// This is the format that's currently used
|
||||
/// </summary>
|
||||
MsalV3
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize SharedTokenCacheClientFactory with CacheMigrationSettings to migrate
|
||||
/// ADAL or MSAL token cache
|
||||
/// </summary>
|
||||
/// <see cref="SharedTokenCacheClientFactory"/>
|
||||
public class CacheMigrationSettings
|
||||
{
|
||||
public byte[] CacheData { get; set; }
|
||||
public CacheFormat CacheFormat { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.Extensions.Caching.Memory;
|
||||
using Microsoft.Identity.Client;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory that creates client app for authenticating with MSAL.
|
||||
/// Should be accessed using <see cref="AuthenticationClientFactory.AuthenticationClientFactoryKey"/>.
|
||||
/// </summary>
|
||||
public class InMemoryTokenCacheClientFactory : AuthenticationClientFactory
|
||||
{
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly string _cacheId = "CacheId";
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
public InMemoryTokenCacheClientFactory()
|
||||
{
|
||||
_memoryCache = new MemoryCache(new MemoryCacheOptions());
|
||||
}
|
||||
|
||||
public override void RegisterCache(IClientApplicationBase client)
|
||||
{
|
||||
client.UserTokenCache.SetBeforeAccess(BeforeAccessNotification);
|
||||
client.UserTokenCache.SetAfterAccess(AfterAccessNotification);
|
||||
}
|
||||
|
||||
private void BeforeAccessNotification(TokenCacheNotificationArgs args)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_memoryCache.TryGetValue(_cacheId, out byte[] blob))
|
||||
{
|
||||
args.TokenCache.DeserializeMsalV3(blob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AfterAccessNotification(TokenCacheNotificationArgs args)
|
||||
{
|
||||
byte[] blob = args.TokenCache.SerializeMsalV3();
|
||||
lock (_lock)
|
||||
{
|
||||
_memoryCache.Set(_cacheId, blob);
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] ReadTokenData()
|
||||
{
|
||||
byte[] blob;
|
||||
lock(_lock)
|
||||
{
|
||||
_memoryCache.TryGetValue(_cacheId, out blob);
|
||||
}
|
||||
return blob;
|
||||
}
|
||||
|
||||
public override void FlushTokenData()
|
||||
{
|
||||
lock(_lock)
|
||||
{
|
||||
_memoryCache.Set(_cacheId, _tokenCacheDataToFlush);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearCache()
|
||||
{
|
||||
_memoryCache.Remove(_cacheId);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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 Hyak.Common;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
using Microsoft.Identity.Client;
|
||||
using Microsoft.Identity.Client.Extensions.Msal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
public class SharedTokenCacheClientFactory : AuthenticationClientFactory
|
||||
{
|
||||
public static readonly string CacheFilePath =
|
||||
Path.Combine(SharedUtilities.GetUserRootDirectory(), ".IdentityService", "msal.cache");
|
||||
|
||||
public override byte[] ReadTokenData()
|
||||
{
|
||||
return GetCacheHelper(PowerShellClientId).LoadUnencryptedTokenCache();
|
||||
}
|
||||
|
||||
public override void FlushTokenData()
|
||||
{
|
||||
GetCacheHelper(PowerShellClientId).SaveUnencryptedTokenCache(_tokenCacheDataToFlush);
|
||||
base.FlushTokenData();
|
||||
}
|
||||
|
||||
private CacheMigrationSettings _cacheMigrationSettings;
|
||||
|
||||
|
||||
/// <exception cref="MsalCachePersistenceException">When the operating system does not support persistence.</exception>
|
||||
public SharedTokenCacheClientFactory()
|
||||
{
|
||||
GetCacheHelper(PowerShellClientId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the client factory with token cache migration settings. Factory will try to migrate the cache before any access to token cache.
|
||||
/// </summary>
|
||||
/// <exception cref="MsalCachePersistenceException">When the operating system does not support persistence.</exception>
|
||||
public SharedTokenCacheClientFactory(CacheMigrationSettings cacheMigrationSettings) : this() =>
|
||||
_cacheMigrationSettings = cacheMigrationSettings;
|
||||
|
||||
private static MsalCacheHelper _helper;
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
private static MsalCacheHelper GetCacheHelper(String clientId)
|
||||
{
|
||||
if (_helper != null)
|
||||
{
|
||||
return _helper;
|
||||
}
|
||||
lock(_lock)
|
||||
{
|
||||
// Double check helper existence
|
||||
if (_helper == null)
|
||||
{
|
||||
_helper = CreateCacheHelper(clientId);
|
||||
}
|
||||
return _helper;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if current environment support token cache persistence
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool SupportCachePersistence(out string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cacheHelper = GetCacheHelper(PowerShellClientId);
|
||||
cacheHelper.VerifyPersistence();
|
||||
}
|
||||
catch (MsalCachePersistenceException e)
|
||||
{
|
||||
message = e.Message;
|
||||
return false;
|
||||
}
|
||||
message = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void RegisterCache(IClientApplicationBase client)
|
||||
{
|
||||
if (_cacheMigrationSettings != null)
|
||||
{
|
||||
// register a one-time handler to deserialize token cache
|
||||
client.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
DeserializeTokenCache(args.TokenCache, _cacheMigrationSettings);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// continue silently
|
||||
TracingAdapter.Information($"[SharedTokenCacheClientFactory] Exception caught trying migrating ADAL cache: {e.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_cacheMigrationSettings = null;
|
||||
// replace the handler with the real one
|
||||
var cacheHelper = GetCacheHelper(client.AppConfig.ClientId);
|
||||
cacheHelper.RegisterCache(client.UserTokenCache);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
var cacheHelper = GetCacheHelper(client.AppConfig.ClientId);
|
||||
cacheHelper.RegisterCache(client.UserTokenCache);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeserializeTokenCache(ITokenCacheSerializer tokenCache, CacheMigrationSettings cacheMigrationSettings)
|
||||
{
|
||||
switch (cacheMigrationSettings.CacheFormat)
|
||||
{
|
||||
case CacheFormat.AdalV3:
|
||||
tokenCache.DeserializeAdalV3(cacheMigrationSettings.CacheData);
|
||||
return;
|
||||
case CacheFormat.MsalV3:
|
||||
tokenCache.DeserializeMsalV3(cacheMigrationSettings.CacheData);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static MsalCacheHelper CreateCacheHelper(string clientId)
|
||||
{
|
||||
var builder = new StorageCreationPropertiesBuilder(Path.GetFileName(CacheFilePath), Path.GetDirectoryName(CacheFilePath), clientId);
|
||||
builder = builder.WithMacKeyChain(serviceName: "Microsoft.Developer.IdentityService", accountName: "MSALCache");
|
||||
builder = builder.WithLinuxKeyring(
|
||||
schemaName: "msal.cache",
|
||||
collection: "default",
|
||||
secretLabel: "MSALCache",
|
||||
attribute1: new KeyValuePair<string, string>("MsalClientID", "Microsoft.Developer.IdentityService"),
|
||||
attribute2: new KeyValuePair<string, string>("MsalClientVersion", "1.0.0.0"));
|
||||
var storageCreationProperties = builder.Build();
|
||||
return MsalCacheHelper.CreateAsync(storageCreationProperties).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public override void ClearCache()
|
||||
{
|
||||
lock (_helper)
|
||||
{
|
||||
_helper.Clear();
|
||||
}
|
||||
base.ClearCache();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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 Hyak.Common;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Properties;
|
||||
using Microsoft.Azure.Commands.ResourceManager.Common;
|
||||
using Microsoft.Identity.Client;
|
||||
using Microsoft.Identity.Client.Extensibility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
public class CustomWebUi : ICustomWebUi
|
||||
{
|
||||
private const string CloseWindowSuccessHtml = @"<html>
|
||||
<head><title>Authentication Complete</title></head>
|
||||
<body>
|
||||
Authentication complete. You can return to the application. Feel free to close this browser tab.
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
public async Task<Uri> AcquireAuthorizationCodeAsync(Uri authorizationUri, Uri redirectUri, CancellationToken cancellationToken)
|
||||
{
|
||||
TracingAdapter.Information(string.Format("[CustomWebUi] Starting AcquireAuthorizationCodeAsync - AuthorizationUri: '{0}', RedirectUri: '{1}'", authorizationUri, redirectUri));
|
||||
WriteWarning(Resources.TryLaunchBrowser);
|
||||
if (!OpenBrowser(authorizationUri.ToString()))
|
||||
{
|
||||
WriteWarning(Resources.UnableToLaunchBrowser);
|
||||
}
|
||||
|
||||
WriteWarning(Resources.SuccessfullyLaunchedBrowser);
|
||||
TcpListener listener = new TcpListener(IPAddress.Loopback, redirectUri.Port);
|
||||
listener.Start();
|
||||
using (TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false))
|
||||
{
|
||||
string httpRequest = await GetTcpResponseAsync(client, cancellationToken).ConfigureAwait(false);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
string uri = ExtractUriFromHttpRequest(httpRequest, redirectUri.Port);
|
||||
await WriteResponseAsync(client.GetStream(), cancellationToken).ConfigureAwait(false);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
TracingAdapter.Information(string.Format("[CustomWebUi] Ending AcquireAuthorizationCodeAsync - Returning URI '{0}'", uri));
|
||||
return await Task.Run(() => { return new Uri(uri); }, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
// No universal call in .NET Core to open browser -- see below issue for more details
|
||||
// https://github.com/dotnet/corefx/issues/10361
|
||||
private bool OpenBrowser(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
url = url.Replace("&", "^&");
|
||||
Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true });
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
Process.Start("xdg-open", url);
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
Process.Start("open", url);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new PlatformNotSupportedException(RuntimeInformation.OSDescription);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static async Task<string> GetTcpResponseAsync(TcpClient client, CancellationToken cancellationToken)
|
||||
{
|
||||
NetworkStream networkStream = client.GetStream();
|
||||
|
||||
byte[] readBuffer = new byte[1024];
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
int numberOfBytesRead = 0;
|
||||
|
||||
// Incoming message may be larger than the buffer size.
|
||||
do
|
||||
{
|
||||
numberOfBytesRead = await networkStream.ReadAsync(readBuffer, 0, readBuffer.Length, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
string s = Encoding.ASCII.GetString(readBuffer, 0, numberOfBytesRead);
|
||||
stringBuilder.Append(s);
|
||||
|
||||
}
|
||||
while (networkStream.DataAvailable);
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
private string ExtractUriFromHttpRequest(string httpRequest, int port)
|
||||
{
|
||||
string regexp = @"GET \/\?(.*) HTTP";
|
||||
string getQuery = null;
|
||||
Regex r1 = new Regex(regexp);
|
||||
Match match = r1.Match(httpRequest);
|
||||
if (!match.Success)
|
||||
{
|
||||
throw new InvalidOperationException("Not a GET query");// TODO: exceptions
|
||||
}
|
||||
|
||||
getQuery = match.Groups[1].Value;
|
||||
UriBuilder uriBuilder = new UriBuilder();
|
||||
uriBuilder.Query = getQuery;
|
||||
uriBuilder.Port = port;
|
||||
Uri u = uriBuilder.Uri;
|
||||
|
||||
return uriBuilder.ToString();
|
||||
}
|
||||
|
||||
private async Task WriteResponseAsync(NetworkStream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
string fullResponse = $"HTTP/1.1 200 OK\r\n\r\n{CloseWindowSuccessHtml}";
|
||||
var response = Encoding.ASCII.GetBytes(fullResponse);
|
||||
await stream.WriteAsync(response, 0, response.Length, cancellationToken).ConfigureAwait(false);
|
||||
await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void WriteWarning(string message)
|
||||
{
|
||||
EventHandler<StreamEventArgs> writeWarningEvent;
|
||||
if (AzureSession.Instance.TryGetComponent(AzureRMCmdlet.WriteWarningKey, out writeWarningEvent))
|
||||
{
|
||||
writeWarningEvent(this, new StreamEventArgs() { Message = message });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,8 +16,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
|
@ -27,20 +29,33 @@ namespace Microsoft.Azure.Commands.Common.Authentication
|
|||
public abstract class DelegatingAuthenticator : IAuthenticator
|
||||
{
|
||||
public IAuthenticator Next { get; set; }
|
||||
public abstract bool CanAuthenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Task<Action<string>> promptAction, IAzureTokenCache tokenCache, string resourceId);
|
||||
public abstract Task<IAccessToken> Authenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Task<Action<string>> promptAction, IAzureTokenCache tokenCache, string resourceId);
|
||||
public bool TryAuthenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Task<Action<string>> promptAction, IAzureTokenCache tokenCache, string resourceId, out Task<IAccessToken> token)
|
||||
public abstract bool CanAuthenticate(AuthenticationParameters parameters);
|
||||
public abstract Task<IAccessToken> Authenticate(AuthenticationParameters parameters, CancellationToken cancellationToken);
|
||||
|
||||
public Task<IAccessToken> Authenticate(AuthenticationParameters parameters)
|
||||
{
|
||||
var source = new CancellationTokenSource();
|
||||
return Authenticate(parameters, source.Token);
|
||||
}
|
||||
|
||||
public bool TryAuthenticate(AuthenticationParameters parameters, out Task<IAccessToken> token)
|
||||
{
|
||||
var source = new CancellationTokenSource();
|
||||
return TryAuthenticate(parameters, source.Token, out token);
|
||||
}
|
||||
|
||||
public bool TryAuthenticate(AuthenticationParameters parameters, CancellationToken cancellationToken, out Task<IAccessToken> token)
|
||||
{
|
||||
token = null;
|
||||
if (CanAuthenticate(account, environment, tenant, password, promptBehavior, promptAction, tokenCache, resourceId))
|
||||
if (CanAuthenticate(parameters))
|
||||
{
|
||||
token = Authenticate(account, environment, tenant, password, promptBehavior, promptAction, tokenCache, resourceId);
|
||||
token = Authenticate(parameters, cancellationToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Next != null)
|
||||
{
|
||||
return Next.TryAuthenticate(account, environment, tenant, password, promptBehavior, promptAction, tokenCache, resourceId, out token);
|
||||
return Next.TryAuthenticate(parameters, cancellationToken, out token);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.Identity.Client;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to platform-specific methods for securely storing client credentials
|
||||
/// </summary>
|
||||
public interface IApplicationAuthenticationProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve ClientCredentials for an active directory application.
|
||||
/// </summary>
|
||||
/// <param name="clientId">The active directory client Id of the application.</param>
|
||||
/// <param name="audience">The audience to target</param>
|
||||
/// <returns>authentication result which can be used for authentication with the given audience.</returns>
|
||||
Task<AuthenticationResult> AuthenticateAsync(string clientId, string audience);
|
||||
}
|
||||
}
|
|
@ -13,8 +13,10 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
|
@ -30,46 +32,42 @@ namespace Microsoft.Azure.Commands.Common.Authentication
|
|||
IAuthenticator Next { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determine if this authenticator can apply to the given authentication parameters
|
||||
/// Determine if this authenticator can apply to the given authentication parameters.
|
||||
/// </summary>
|
||||
/// <param name="account">The account to authenticate</param>
|
||||
/// <param name="environment">The environment to authenticate in</param>
|
||||
/// <param name="tenant">The tenant</param>
|
||||
/// <param name="password">The secure credentials for the given account</param>
|
||||
/// <param name="promptBehavior">The desired prompting behavior during authentication</param>
|
||||
/// <param name="promptAction">Action to take if the user need to be prompted</param>
|
||||
/// <param name="tokenCache">The token cache to use in this authentication</param>
|
||||
/// <param name="resourceId">The resource that will need proof of authentication</param>
|
||||
/// <returns>true if this authenticator can be applied to the given parameters, otherwise false</returns>
|
||||
bool CanAuthenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Task<Action<string>> promptAction, IAzureTokenCache tokenCache, string resourceId);
|
||||
/// <param name="parameters">The complex object containing authentication specific information (e.g., tenant, token cache, etc.)</param>
|
||||
/// <returns></returns>
|
||||
bool CanAuthenticate(AuthenticationParameters parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Apply this authenticator to the given authentication parameters
|
||||
/// </summary>
|
||||
/// <param name="account">The account to authenticate</param>
|
||||
/// <param name="environment">The environment to authenticate in</param>
|
||||
/// <param name="tenant">The tenant</param>
|
||||
/// <param name="password">The secure credentials for the given account</param>
|
||||
/// <param name="promptBehavior">The desired prompting behavior during authentication</param>
|
||||
/// <param name="promptAction">Action to take if the user need to be prompted</param>
|
||||
/// <param name="tokenCache">The token cache to use in this authentication</param>
|
||||
/// <param name="resourceId">The resource that will need proof of authentication</param>
|
||||
/// <returns>The token based authntication information</returns>
|
||||
Task<IAccessToken> Authenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Task<Action<string>> promptAction, IAzureTokenCache tokenCache, string resourceId);
|
||||
/// <param name="parameters">The complex object containing authentication specific information (e.g., tenant, token cache, etc.)</param>
|
||||
/// <returns></returns>
|
||||
Task<IAccessToken> Authenticate(AuthenticationParameters parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if this request can be authenticated using the given authenticaotr, and authenticate if it can
|
||||
/// Apply this authenticator to the given authentication parameters
|
||||
/// </summary>
|
||||
/// <param name="account">The account to authenticate</param>
|
||||
/// <param name="environment">The environment to authenticate in</param>
|
||||
/// <param name="tenant">The tenant</param>
|
||||
/// <param name="password">The secure credentials for the given account</param>
|
||||
/// <param name="promptBehavior">The desired prompting behavior during authentication</param>
|
||||
/// <param name="promptAction">Action to take if the user need to be prompted</param>
|
||||
/// <param name="tokenCache">The token cache to use in this authentication</param>
|
||||
/// <param name="resourceId">The resource that will need proof of authentication</param>
|
||||
/// <param name="token">The token based authntication information</param>
|
||||
/// <returns>true if the request was authenticated, otherwise false</returns>
|
||||
bool TryAuthenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Task<Action<string>> promptAction, IAzureTokenCache tokenCache, string resourceId, out Task<IAccessToken> token);
|
||||
/// <param name="parameters">The complex object containing authentication specific information (e.g., tenant, token cache, etc.)</param>
|
||||
/// <param name="cancellationToken">The cancellation token provided from the cmdlet to halt authentication.</param>
|
||||
/// <returns></returns>
|
||||
Task<IAccessToken> Authenticate(AuthenticationParameters parameters, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if this request can be authenticated using the given authenticator, and authenticate if it can
|
||||
/// </summary>
|
||||
/// <param name="parameters">The complex object containing authentication specific information (e.g., tenant, token cache, etc.)</param>
|
||||
/// <param name="token">The token based authentication information</param>
|
||||
/// <returns></returns>
|
||||
bool TryAuthenticate(AuthenticationParameters parameters, out Task<IAccessToken> token);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if this request can be authenticated using the given authenticator, and authenticate if it can
|
||||
/// </summary>
|
||||
/// <param name="parameters">The complex object containing authentication specific information (e.g., tenant, token cache, etc.)</param>
|
||||
/// <param name="cancellationToken">The cancellation token provided from the cmdlet to halt authentication.</param>
|
||||
/// <param name="token">The token based authentication information</param>
|
||||
/// <returns></returns>
|
||||
bool TryAuthenticate(AuthenticationParameters parameters, CancellationToken cancellationToken, out Task<IAccessToken> token);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication
|
|||
{
|
||||
public class ManagedServiceAccessToken : ManagedServiceAccessTokenBase<ManagedServiceTokenInfo>
|
||||
{
|
||||
public ManagedServiceAccessToken(IAzureAccount account, IAzureEnvironment environment, string resourceId, string tenant = "Common")
|
||||
public ManagedServiceAccessToken(IAzureAccount account, IAzureEnvironment environment, string resourceId, string tenant = "organizations")
|
||||
: base(account, environment, resourceId, tenant)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication
|
|||
protected DateTimeOffset Expiration = DateTimeOffset.Now;
|
||||
protected string accessToken;
|
||||
|
||||
protected ManagedServiceAccessTokenBase(IAzureAccount account, IAzureEnvironment environment, string resourceId, string tenant = "Common")
|
||||
protected ManagedServiceAccessTokenBase(IAzureAccount account, IAzureEnvironment environment, string resourceId, string tenant = "organizations")
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(account?.Id) || !account.IsPropertySet(AzureAccount.Property.MSILoginUri))
|
||||
{
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Microsoft.Azure.Commands.Common.Authentication
|
|||
{
|
||||
public class ManagedServiceAppServiceAccessToken : ManagedServiceAccessTokenBase<ManagedServiceAppServiceTokenInfo>
|
||||
{
|
||||
public ManagedServiceAppServiceAccessToken(IAzureAccount account, IAzureEnvironment environment, string tenant = "Common")
|
||||
public ManagedServiceAppServiceAccessToken(IAzureAccount account, IAzureEnvironment environment, string tenant = "organizations")
|
||||
: base(account, environment, @"https://management.azure.com/", tenant)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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 System;
|
||||
using System.Security;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Properties;
|
||||
using Microsoft.Azure.Commands.Common.Authentication.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
/// <summary>
|
||||
/// A token provider that uses ADAL to retrieve
|
||||
/// tokens from Azure Active Directory
|
||||
/// </summary>
|
||||
public class MsalTokenProvider : ITokenProvider
|
||||
{
|
||||
private readonly ITokenProvider userTokenProvider;
|
||||
private readonly ITokenProvider servicePrincipalTokenProvider;
|
||||
|
||||
public MsalTokenProvider(Func<IServicePrincipalKeyStore> getKeyStore)
|
||||
{
|
||||
this.userTokenProvider = new UserTokenProvider();
|
||||
this.servicePrincipalTokenProvider = new ServicePrincipalTokenProvider(getKeyStore);
|
||||
}
|
||||
|
||||
public IAccessToken GetAccessToken(
|
||||
AdalConfiguration config,
|
||||
string promptBehavior,
|
||||
Action<string> promptAction,
|
||||
string userId,
|
||||
SecureString password,
|
||||
string credentialType)
|
||||
{
|
||||
switch (credentialType)
|
||||
{
|
||||
case AzureAccount.AccountType.User:
|
||||
return userTokenProvider.GetAccessToken(
|
||||
config,
|
||||
promptBehavior,
|
||||
promptAction,
|
||||
userId,
|
||||
password,
|
||||
credentialType);
|
||||
case AzureAccount.AccountType.ServicePrincipal:
|
||||
return servicePrincipalTokenProvider.GetAccessToken(
|
||||
config,
|
||||
promptBehavior,
|
||||
promptAction,
|
||||
userId,
|
||||
password,
|
||||
credentialType);
|
||||
default:
|
||||
throw new ArgumentException(Resources.UnsupportedCredentialType, "credentialType");
|
||||
}
|
||||
}
|
||||
|
||||
public IAccessToken GetAccessTokenWithCertificate(
|
||||
AdalConfiguration config,
|
||||
string clientId,
|
||||
string certificate,
|
||||
string credentialType)
|
||||
{
|
||||
switch (credentialType)
|
||||
{
|
||||
case AzureAccount.AccountType.ServicePrincipal:
|
||||
return servicePrincipalTokenProvider.GetAccessTokenWithCertificate(config, clientId, certificate, credentialType);
|
||||
default:
|
||||
throw new ArgumentException(string.Format(Resources.UnsupportedCredentialType, credentialType), "credentialType");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
public class AccessTokenParameters : AuthenticationParameters
|
||||
{
|
||||
public IAzureAccount Account { get; set; }
|
||||
|
||||
public AccessTokenParameters(
|
||||
AuthenticationClientFactory authenticationClientFactory,
|
||||
IAzureEnvironment environment,
|
||||
IAzureTokenCache tokenCache,
|
||||
string tenantId,
|
||||
string resourceId,
|
||||
IAzureAccount account) : base(authenticationClientFactory, environment, tokenCache, tenantId, resourceId)
|
||||
{
|
||||
Account = account;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
public abstract class AuthenticationParameters
|
||||
{
|
||||
public AuthenticationClientFactory AuthenticationClientFactory { get; set; }
|
||||
|
||||
public IAzureEnvironment Environment { get; set; }
|
||||
|
||||
public IAzureTokenCache TokenCache { get; set; }
|
||||
|
||||
public string TenantId { get; set; }
|
||||
|
||||
public string ResourceId { get; set; }
|
||||
|
||||
public AuthenticationParameters(
|
||||
AuthenticationClientFactory authenticationClientFactory,
|
||||
IAzureEnvironment environment,
|
||||
IAzureTokenCache tokenCache,
|
||||
string tenantId,
|
||||
string resourceId)
|
||||
{
|
||||
AuthenticationClientFactory = authenticationClientFactory;
|
||||
Environment = environment;
|
||||
TokenCache = tokenCache;
|
||||
TenantId = tenantId;
|
||||
ResourceId = resourceId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.Authentication.Clients;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
public class DeviceCodeParameters : AuthenticationParameters
|
||||
{
|
||||
public DeviceCodeParameters(
|
||||
AuthenticationClientFactory authenticationClientFactory,
|
||||
IAzureEnvironment environment,
|
||||
IAzureTokenCache tokenCache,
|
||||
string tenantId,
|
||||
string resourceId) : base(authenticationClientFactory, environment, tokenCache, tenantId, resourceId) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
// 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.Authentication.Clients;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Azure.Commands.Common.Authentication
|
||||
{
|
||||
public class InteractiveParameters : DeviceCodeParameters
|
||||
{
|
||||
public Action<string> PromptAction { get; set; }
|
||||
|
||||
public InteractiveParameters(
|
||||
AuthenticationClientFactory authenticationClientFactory,
|
||||
IAzureEnvironment environment,
|
||||
IAzureTokenCache tokenCache,
|
||||
string tenantId,
|
||||
string resourceId,
|
||||
Action<string> promptAction) : base(authenticationClientFactory, environment, tokenCache, tenantId, resourceId)
|
||||
{
|
||||
PromptAction = promptAction;
|
||||
}
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче