Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5e1c70d
Common code package updates
cormacpayne Sep 4, 2019
5c2f22e
Changes to Authenticators
cormacpayne Sep 4, 2019
c95077b
Changes to lib folder assemblies
cormacpayne Sep 4, 2019
17a60ca
Add classes from ClientRuntime Authentication library (allows us to r…
cormacpayne Sep 4, 2019
3522bc5
Add new client factory classes
cormacpayne Sep 4, 2019
a672d35
Changes to AuthenticationFactory (CoR pattern used)
cormacpayne Sep 4, 2019
32f5bd8
Changes to AzureRmProfile (context update logic)
cormacpayne Sep 4, 2019
094542a
Other changes in Accounts project
cormacpayne Sep 4, 2019
b1a4104
Other changes in Authentication project
cormacpayne Sep 4, 2019
08f6886
Miscellaneous changes in other projects
cormacpayne Sep 4, 2019
00b20f0
Merge branch 'master' of https://github.com/Azure/azure-powershell in…
cormacpayne Sep 10, 2019
6478c36
Resolving a few comments from feedback
cormacpayne Sep 16, 2019
4985264
Add missing assemblies to Az.Accounts.psd1
cormacpayne Sep 16, 2019
2a772b5
Fix issue with ADFS authentication across different authenticators
cormacpayne Sep 17, 2019
9e5ad5b
CancellationToken support in authenticators, update error logic when …
cormacpayne Sep 17, 2019
71e05c1
Add logging and tracing for MSAL calls
cormacpayne Sep 19, 2019
d3f9aa9
Temporarily patch linux failure
markcowl Oct 8, 2019
551fc76
adopt latest common code
isra-fel Oct 17, 2019
fbcc1dc
make test pass
isra-fel Oct 21, 2019
6cd831a
typo
isra-fel Oct 22, 2019
921b7cd
use latest version of msal and extensions
isra-fel Oct 24, 2019
9c9c7c8
preload netfx msal extensions; not msal
isra-fel Nov 4, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .azure-pipelines/powershell-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ jobs:
windows:
OSName: ${{ variables.WindowsName }}
ImageName: ${{ variables.WindowsImage }}
linux:
OSName: ${{ variables.LinuxName }}
ImageName: ${{ variables.LinuxImage }}
macOS:
OSName: ${{ variables.MacOSName }}
ImageName: ${{ variables.MacOSImage }}
Expand All @@ -43,9 +40,6 @@ jobs:
windows:
OSName: ${{ variables.WindowsName }}
ImageName: ${{ variables.WindowsImage }}
linux:
OSName: ${{ variables.LinuxName }}
ImageName: ${{ variables.LinuxImage }}
macOS:
OSName: ${{ variables.MacOSName }}
ImageName: ${{ variables.MacOSImage }}
Expand All @@ -68,9 +62,6 @@ jobs:
windows:
OSName: ${{ variables.WindowsName }}
ImageName: ${{ variables.WindowsImage }}
linux:
OSName: ${{ variables.LinuxName }}
ImageName: ${{ variables.LinuxImage }}
macOS:
OSName: ${{ variables.MacOSName }}
ImageName: ${{ variables.MacOSImage }}
Expand Down
10 changes: 6 additions & 4 deletions src/Accounts/Accounts.Test/ContextCmdletTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
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
{
Expand Down Expand Up @@ -196,7 +197,7 @@ public void ListMultipleContexts()
var profile = CreateMultipleContextProfile();
cmdlet.CommandRuntime = commandRuntimeMock;
cmdlet.DefaultProfile = profile;
cmdlet.ListAvailable = true;
cmdlet.MyInvocation.BoundParameters.Add("ListAvailable", true);
cmdlet.InvokeBeginProcessing();
cmdlet.ExecuteCmdlet();
cmdlet.InvokeEndProcessing();
Expand Down Expand Up @@ -262,8 +263,8 @@ public void RemoveDefaultContext()
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();
Expand All @@ -289,8 +290,8 @@ public void RemoveNonDefaultContext()
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();
Expand Down Expand Up @@ -610,6 +611,8 @@ public void RenameContextNoLogin()
[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;
Expand All @@ -630,7 +633,6 @@ public void ClearMultipleContexts()
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]
Expand Down
72 changes: 68 additions & 4 deletions src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
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;

namespace Microsoft.Azure.Commands.Profile
{
Expand Down Expand Up @@ -57,7 +63,7 @@ public class ConnectAzureRmAccountCommand : AzureContextModificationCmdlet, IMod
[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,
Expand Down Expand Up @@ -184,6 +190,18 @@ protected override void BeginProcessing()
string.Format(Resources.UnknownEnvironment, Environment));
}
}

_writeWarningEvent -= WriteWarningSender;
_writeWarningEvent += WriteWarningSender;
AzureSession.Instance.UnregisterComponent<EventHandler<StreamEventArgs>>(WriteWarningKey);
AzureSession.Instance.RegisterComponent("WriteWarning", () => _writeWarningEvent);
}

private event EventHandler<StreamEventArgs> _writeWarningEvent;

private void WriteWarningSender(object sender, StreamEventArgs args)
{
_tasks.Enqueue(new Task(() => this.WriteWarning(args.Message)));
}

public override void ExecuteCmdlet()
Expand Down Expand Up @@ -241,7 +259,7 @@ public override void ExecuteCmdlet()
? 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
Expand Down Expand Up @@ -322,7 +340,14 @@ public override void ExecuteCmdlet()

SetContextWithOverwritePrompt((localProfile, profileClient, name) =>
{
WriteObject((PSAzureProfile)profileClient.Login(
bool? skipContextPopulationList = null;
if (this.IsParameterBound(c => c.SkipContextPopulation))
{
skipContextPopulationList = false;
}

profileClient.WarningLog = (message) => _tasks.Enqueue(new Task(() => this.WriteWarning(message)));
var task = new Task<AzureRmProfile>( () => profileClient.Login(
azureAccount,
_environment,
Tenant,
Expand All @@ -332,11 +357,32 @@ public override void ExecuteCmdlet()
SkipValidation,
WriteWarning,
name,
!SkipContextPopulation.IsPresent));
skipContextPopulationList));
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 static bool CheckForExistingContext(AzureRmProfile profile, string name)
{
return name != null && profile?.Contexts != null && profile.Contexts.ContainsKey(name);
Expand Down Expand Up @@ -396,6 +442,24 @@ public void OnImport()
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);
}

if (autoSaveEnabled)
{
AuthenticationClientFactory factory = new SharedTokenCacheClientFactory();
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
}
else
{
AuthenticationClientFactory factory = new InMemoryTokenCacheClientFactory();
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
}
#if DEBUG
}
catch (Exception) when (TestMockSupport.RunningMocked)
Expand Down
24 changes: 19 additions & 5 deletions src/Accounts/Accounts/Accounts.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@
<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.Extensions.Msal\NetFx\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>
Expand Down Expand Up @@ -51,7 +49,23 @@

<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>
<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>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
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
{
Expand Down Expand Up @@ -80,14 +82,17 @@ void DisableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextA
{
var diskCache = session.TokenCache as ProtectedFileTokenCache;
memoryCache = new AuthenticationStoreTokenCache(new AzureTokenCache());
if (diskCache != null && diskCache.Count > 0)
if (diskCache != null)
{
memoryCache.Deserialize(diskCache.Serialize());
memoryCache.CacheData = diskCache.CacheData;
}

session.TokenCache = memoryCache;
}

AuthenticationClientFactory authenticationClientFactory = new InMemoryTokenCacheClientFactory(cacheToMigratePath: SharedTokenCacheClientFactory.CacheFilePath);
AzureSession.Instance.UnregisterComponent<AuthenticationClientFactory>(AuthenticationClientFactory.AuthenticationClientFactoryKey);
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => authenticationClientFactory);
if (writeAutoSaveFile)
{
FileUtilities.EnsureDirectoryExists(session.ProfileDirectory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
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
{
Expand Down Expand Up @@ -93,9 +95,9 @@ void EnableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextAu
FileUtilities.EnsureDirectoryExists(session.TokenCacheDirectory);

diskCache = new ProtectedFileTokenCache(tokenPath, store);
if (memoryCache != null && memoryCache.Count > 0)
if (memoryCache != null)
{
diskCache.Deserialize(memoryCache.Serialize());
diskCache.CacheData = memoryCache.CacheData;
}

session.TokenCache = diskCache;
Expand All @@ -106,6 +108,9 @@ void EnableAutosave(IAzureSession session, bool writeAutoSaveFile, out ContextAu
}
}

AuthenticationClientFactory factory = new SharedTokenCacheClientFactory();
AzureSession.Instance.UnregisterComponent<AuthenticationClientFactory>(AuthenticationClientFactory.AuthenticationClientFactoryKey);
AzureSession.Instance.RegisterComponent(AuthenticationClientFactory.AuthenticationClientFactoryKey, () => factory);
if (writeAutoSaveFile)
{
try
Expand Down
16 changes: 15 additions & 1 deletion src/Accounts/Accounts/Az.Accounts.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,21 @@ RequiredAssemblies = '.\Microsoft.Azure.PowerShell.Authentication.Abstractions.d
'.\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.Configuration.Abstractions.dll',
'.\Microsoft.Extensions.Configuration.Binder.dll',
'.\Microsoft.Extensions.Configuration.dll',
'.\Microsoft.Extensions.Configuration.EnvironmentVariables.dll',
'.\Microsoft.Extensions.DependencyInjection.Abstractions.dll',
'.\Microsoft.Extensions.Logging.Abstractions.dll',
'.\Microsoft.Extensions.Options.dll',
'.\Microsoft.Extensions.Primitives.dll',
'.\Microsoft.Identity.Client.dll',
'.\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 = @()
Expand Down
12 changes: 12 additions & 0 deletions src/Accounts/Accounts/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@
-->
## Upcoming Release

## 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.6.2
* Fixed miscellaneous typos across module
* Support user-assigned MSI in Azure Functions Authentication (#9479)
Expand Down
10 changes: 7 additions & 3 deletions src/Accounts/Accounts/Common/AzureContextModificationCmdlet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -43,7 +44,11 @@ protected virtual void ModifyContext(Action<AzureRmProfile, RMProfileClient> con
{
using (var profile = GetDefaultProfile())
{
contextAction(profile.ToProfile(), new RMProfileClient(profile));
var client = new RMProfileClient(profile)
{
WarningLog = (s) => WriteWarning(s)
};
contextAction(profile.ToProfile(), client);
}
}

Expand Down Expand Up @@ -83,7 +88,7 @@ protected virtual IProfileOperations GetDefaultProfile()
/// <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()
{
Expand Down Expand Up @@ -193,6 +198,5 @@ protected bool TryGetExistingContextNameParameter(string name, string parameterS

return result;
}

}
}
Loading