Skip to content

Commit fcfcc03

Browse files
authored
Merge pull request #17760 from wastoresh/mergestorage
[Do no Squash][Storage] merge main change to storage preview branch
2 parents 2265df8 + 6c69354 commit fcfcc03

File tree

13 files changed

+561
-537
lines changed

13 files changed

+561
-537
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Authentication
2+
## Overview
3+
4+
All authentication in PowerShell follows the same basic method. All requests are authenticated with a token, that is provided by a token service. The token identifies the principal, and the services (also called resources) that the user wants to access (and the STS can verify that the user is registered to access). Services use this token to identify the principal, and associate the user with the appropriate authorization level. Authorization is managed separately, by each service, and is not part of this discussion.
5+
6+
This document breaks down PowerShell Authentication into the following sections
7+
- Abstractions - Discusses the Concepts used in authenticating a user
8+
- Authentication Scenarios - Discusses the various authentication methods that can be used by each kind of principal
9+
- User Authentication
10+
- Service Authentication
11+
- MSI Authentication
12+
- Token Authentication
13+
- MSAL Authentication - Discusses how these scenarios differ in MSAL
14+
15+
## Abstractions
16+
17+
### Context
18+
The context is the default target of any cmdlet executed in PowerShell. It consists of the [`Account`](#account), [`Tenant`](#tenant]), [`Environment`](#environment), and [`Subscription`](#subscription) that the user has selected using the `Select-AzContext` or `Select-AzSubscription` cmdlets. It also contains a reference to the token cache that is used in Authentication. For most cmdlets, the subscription or tenant they target for their calls is the subscription/tenant in the `Default` Context.
19+
20+
### ContextContainer
21+
A context container is a collection of contexts - it contains a dictionary associating its context with a unique key, and a `Default` context which is the context currently selected. The user can switch between any contexts in the container without additional login. The ContextContainer is populated when the user authenticates for the first time.
22+
23+
### Account
24+
An account is the representation of the principal used for authentication. This can be a User Account, a Service Principal, a Managed Service Identity, or a raw token. The primary key for Account is a name. In the case of user authentication, this will be of the form ```<user>@<domain>```, for example ```[email protected]```. For service principal authentication, the name is the oid of the service principal object. In the case of MSI, the name can be the oid, clientId, or resource id of the associated MSI. For tokens, the name is the token hash.
25+
26+
### Subscription
27+
A subscription represents a subscription in Azure, it has properties indicating ID, Name, and State. The default subscription (that is the description in the `Default` context) will be the target of all cmdlets.
28+
29+
### Environment
30+
An Environment is a particular Azure cloud that is targeted for commands. 'AzureCloud' is the default environment if none is selected. Built-in clouds also include 'AzureChinaCloud', 'AzureGermanCloud', and 'AzureUSGovernment' cloud. Each environment contains the endpoints for services on that cloud, the 'resourceId' that is required when authenticating for that service, and a set of domain suffixes that can be used to determine data plane service endpoints (for example, the StorageEndpointSuffix can be appended to a storage account name to get the default domain name of the endpoints for that storage account).
31+
32+
### Tenant
33+
A Tenant represents an Active Directory tenant that may contain one or more subscriptions. When authenticating, a user may have access to multiple tenants, and the default ContextContainer will contain all of the tenants (and associated subscriptions) the user has access to.
34+
35+
### Caching
36+
Each context contains a reference to the currently active TokenCache - this allows common Authentication methods to retrieve tokens for the given context when it is passed in to common methods.
37+
38+
### AuthenticationFactory
39+
40+
The Authentication Factory is a central abstraction used by all modules to acquire authentication tokens for their calls to Azure services. This abstract factory is used by Az.Accounts to do initial login and context acquisition, and by service modules to acquire tokens using the currently selected context for their Azure requests (management and data plane). Generally, a client needs to pass in the current context and an indication of what service the user want to authenticate with to get back authentication tokens.
41+
42+
Generally, the types returned by the Authentication Factory encapsulate the actual tokens, so that tokens can be automatically renewed as requests are made without additional explicit calls from the service module.
43+
44+
## Authentication Scenarios
45+
46+
### User Authentication
47+
In User Authentication, Azure PowerShell authenticates on behalf of a user in the authenticating tenant. The privileges granted will be those privileges that the user is assigned.
48+
49+
#### Overview
50+
In user authentication, powershell authenticates to the tenant on behalf of the user. The authentication methods are essentially mechanisms for the user to supply their credentials for authentication.
51+
52+
#### Interactive Authentication
53+
In this mechanism, the user is presented with a browser window pointing at the authentication website to provide credentials. PowerShell supplies a callback that the token service calls once authentication is complete, returning the authentication results. This callback must match one of the 'replyUrls' configured for the application. In PowerShell's case, this configuration is in the first party app registration for PowerShell.
54+
55+
#### Username/Password Authentication
56+
In this mechanism, the user provides a PSCredential with username and password, and powershell authenticates with the token service on the user's behalf. This authentication mechanism is not encouraged, because it precludes the use of multi-factor authentication (MFA), which is a security best practice. However, it is still used in some legacy customer scenarios.
57+
58+
#### DeviceCode Authentication
59+
In this mechanism, the user is given a URI and a code. They must open a browser and navigate to the given URI and supply the given code, then they proceed with interactive authentication as above. DeviceCode authentication is useful for remote terminal access, as the user can authenticate on a remote machine using their local browser.
60+
61+
### Service Authentication
62+
Service authentication authenticates PowerShell as a service principal, rather than a user principal. Service Principal authentication is the recommended method for authenticating scripts that are executed without interaction (for example, scripts run on a particular schedule, or automatically triggered by a particular event). This is because the service used to authenticate may be restricted to only those functions required by the specific script. Additionally, service principal authentication returns authentication tokens, but never renewal tokens.
63+
64+
In service authentication, the script must present the service id and a credential - either a secret string, or a certificate private key, depending on how the service principal is configured. The token service returns a token. Note that, for all of the common code methods used for authentication, service principal credentials are stored in the output type, so that a new token can be automatically acquired when the access token expires, transparently to the user of the returned token abstraction.
65+
66+
### MSI Authentication
67+
MSI authentication is essentially a managed version of service authentication. An Azure resource (such as a VM or AppService) is assigned a service principal, and the credentials of the service principal are managed without the user's intervention. This allows credentials to be propagated to a VM and rotated without the user's intervention or knowledge.
68+
69+
Any code running on an Azure Resource associated with an MSI may acquire a token using a GET request to the local token service on that resource. The token service then authenticates using the underlying service principal and credential, and returns the authentication result as the response to the GET request. As with other authentication types, all MSI authentication performed by common code returns an abstraction over the token that automatically and transparently renews the token when needed (by making additional calls to the local token service).
70+
71+
### Token Authentication
72+
In token authentication, the user simply provides an access token that want to use for accessing Azure. The token the user supplies in `Connect-AzAccount` is simply added to the Authorization header for requests. Generally, the user is allowed to provide one token for each of the services that they need to authenticate wth (ARM, Graph, KeyVault, etc.). While, for parallelism, this authentication type also returns an abstraction that allows the user to renew tokens, token renewal will always fail, since no refresh token is provided, and no credential is provide that would allow re-authentication.
73+
74+
Use of token authentication is an advanced scenario.
75+
76+
## MSAL Authentication
77+
TBD

src/EventHub/EventHub/ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
-->
2020
## Upcoming Release
2121

22+
* Deprecating older MSI related fields in New-AzEventHubNamespace and Set-AzEventHubNamespace
23+
2224
## Version 1.11.0
2325
* Added MSI properties to New-AzEventHubNamespace and Set-AzEventHubNamespace. Adding New-AzEventHubEncryptionConfig.
2426

src/EventHub/EventHub/Cmdlets/Namespace/NewAzureEventHubNamespace.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace Microsoft.Azure.Commands.EventHub.Commands.Namespace
2626
/// <summary>
2727
/// this commandlet will let you Create Eventhub namespace.
2828
/// </summary>
29-
[CmdletOutputBreakingChange(typeof(PSNamespaceAttributes), DeprecatedOutputProperties = new string[] {"ResourceGroup"}, NewOutputProperties = new string[] { "ResourceGroupName", "Tags"})]
29+
[CmdletOutputBreakingChange(typeof(PSNamespaceAttributes), DeprecatedOutputProperties = new string[] {"ResourceGroup", "Identity"}, NewOutputProperties = new string[] { "ResourceGroupName", "Tags", "IdentityType"})]
3030
[Cmdlet("New", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "EventHubNamespace", SupportsShouldProcess = true, DefaultParameterSetName = NamespaceParameterSet), OutputType(typeof(PSNamespaceAttributes))]
3131
public class NewAzureEventHubNamespace : AzureEventHubsCmdletBase
3232
{

src/EventHub/EventHub/Cmdlets/Namespace/SetAzureEventHubNamespace.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace Microsoft.Azure.Commands.EventHub.Commands.Namespace
2727
/// <summary>
2828
/// 'Set-AzEventHubNamespace' Cmdlet updates the specified Eventhub Namespace
2929
/// </summary>
30-
[CmdletOutputBreakingChange(typeof(PSNamespaceAttributes), DeprecatedOutputProperties = new string[] { "ResourceGroup" }, NewOutputProperties = new string[] { "ResourceGroupName", "Tags" })]
30+
[CmdletOutputBreakingChange(typeof(PSNamespaceAttributes), DeprecatedOutputProperties = new string[] { "ResourceGroup", "IdentityUserDefined", "Identity", "KeyProperty" }, NewOutputProperties = new string[] { "ResourceGroupName", "Tags", "IdentityType", "EncryptionConfig" })]
3131
[Cmdlet("Set", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "EventHubNamespace", SupportsShouldProcess = true, DefaultParameterSetName = NamespaceParameterSet), OutputType(typeof(PSNamespaceAttributes))]
3232
public class SetAzureEventHubNamespace : AzureEventHubsCmdletBase
3333
{

src/Network/Network/PrivateLinkService/PrivateLinkServiceProvider/ProviderConfiguration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ static ProviderConfiguration()
2626
RegisterConfiguration("Microsoft.Compute/diskAccesses", "2020-09-30", true, false);
2727
RegisterConfiguration("Microsoft.ContainerRegistry/registries", "2019-12-01-preview", true, false);
2828
RegisterConfiguration("Microsoft.ContainerService/managedClusters", "2021-07-01", true, false);
29+
RegisterConfiguration("Microsoft.Databricks/workspaces", "2021-04-01-preview", true, true);
2930
RegisterConfiguration("Microsoft.DataFactory/factories", "2018-06-01", true, false);
3031
RegisterConfiguration("Microsoft.DBforMariaDB/servers", "2018-06-01", true, true);
3132
RegisterConfiguration("Microsoft.DBforMySQL/servers", "2018-06-01", true, true);

src/Storage/Storage.Management/Az.Storage.psd1

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#
44
# Generated by: Microsoft Corporation
55
#
6-
# Generated on: 3/31/2022
6+
# Generated on: 4/7/2022
77
#
88

99
@{
@@ -12,7 +12,7 @@
1212
# RootModule = ''
1313

1414
# Version number of this module.
15-
ModuleVersion = '4.4.0'
15+
ModuleVersion = '4.4.1'
1616

1717
# Supported PSEditions
1818
CompatiblePSEditions = 'Core', 'Desktop'
@@ -248,21 +248,8 @@ PrivateData = @{
248248
# IconUri = ''
249249

250250
# ReleaseNotes of this module
251-
ReleaseNotes = '* Updated examples in reference documentation for ''Close-AzStorageFileHandle''
252-
* Supported create storage context with customized blob, queue, file, table service endpoint
253-
- ''New-AzStorageContext''
254-
* Fixed copy blob failure on Premium Storage account, or account enabled hierarchical namespace
255-
- ''Copy-AzStorageBlob''
256-
* Supported create account SAS token, container SAS token, blob SAS token with EncryptionScope
257-
- ''New-AzStorageAccountSASToken''
258-
- ''New-AzStorageContainerSASToken''
259-
- ''New-AzStorageBlobSASToken''
260-
* Supported asynchronous blob copy run on new API version
261-
- ''Start-AzStorageBlobCopy''
262-
* Fixed IpRule examples in help
263-
- ''Add-AzStorageAccountNetworkRule''
264-
- ''Remove-AzStorageAccountNetworkRule''
265-
- ''Update-AzStorageAccountNetworkRuleSet'''
251+
ReleaseNotes = '* Fixed get blob by tag failure on Powershell 7.2.2
252+
- ''Get-AzStorageBlobByTag'''
266253

267254
# Prerelease string of this module
268255
Prerelease = 'preview'

src/Storage/Storage.Management/ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
* Supported create storage account with DnsEndpointType
2222
- `New-AzStorageAccount`
2323

24+
## Version 4.4.1
25+
* Fixed get blob by tag failure on Powershell 7.2.2
26+
- `Get-AzStorageBlobByTag`
27+
2428
## Version 4.4.0
2529
* Updated examples in reference documentation for `Close-AzStorageFileHandle`
2630
* Supported create storage context with customized blob, queue, file, table service endpoint

src/Storage/Storage.Management/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@
4646
// You can specify all the values or you can default the Build and Revision Numbers
4747
// by using the '*' as shown below:
4848

49-
[assembly: AssemblyVersion("4.4.0")]
50-
[assembly: AssemblyFileVersion("4.4.0")]
49+
[assembly: AssemblyVersion("4.4.1")]
50+
[assembly: AssemblyFileVersion("4.4.1")]

src/Storage/Storage/Blob/Cmdlet/GetAzureStorageBlob.cs

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -380,50 +380,6 @@ internal async Task ListBlobsByPrefix(long taskId, IStorageBlobManagement localC
380380
}
381381
}
382382

383-
/// <summary>
384-
/// list blobs by blob Tag
385-
/// </summary>
386-
/// <param name="containerName">container name</param>
387-
/// <param name="prefix">blob preifx</param>
388-
/// <returns>An enumerable collection of IListBlobItem</returns>
389-
internal async Task ListBlobsByTag(long taskId, IStorageBlobManagement localChannel, string tagFilterSqlExpression)
390-
{
391-
392-
BlobServiceClient blobServiceClient = Util.GetTrack2BlobServiceClient(localChannel.StorageContext, ClientOptions);
393-
394-
int listCount = InternalMaxCount;
395-
int MaxListCount = 5000;
396-
int requestCount = MaxListCount;
397-
int realListCount = 0;
398-
BlobContinuationToken continuationToken = ContinuationToken;
399-
string track2ContinuationToken = this.ContinuationToken is null ? null : this.ContinuationToken.NextMarker;
400-
401-
do
402-
{
403-
requestCount = Math.Min(listCount, MaxListCount);
404-
realListCount = 0;
405-
IAsyncEnumerator<Page<TaggedBlobItem>> enumerator = blobServiceClient.FindBlobsByTagsAsync(tagFilterSqlExpression, CmdletCancellationToken)
406-
.AsPages(track2ContinuationToken, requestCount)
407-
.GetAsyncEnumerator();
408-
409-
Page<TaggedBlobItem> page;
410-
await enumerator.MoveNextAsync().ConfigureAwait(false);
411-
page = enumerator.Current;
412-
foreach (TaggedBlobItem item in page.Values)
413-
{
414-
BlobContainerClient track2container = blobServiceClient.GetBlobContainerClient(item.BlobContainerName);
415-
OutputStream.WriteObject(taskId, GetAzureStorageBlob(item, track2container, localChannel.StorageContext, page.ContinuationToken, ClientOptions));
416-
realListCount++;
417-
}
418-
track2ContinuationToken = page.ContinuationToken;
419-
420-
if (InternalMaxCount != int.MaxValue)
421-
{
422-
listCount -= realListCount;
423-
}
424-
} while (listCount > 0 && !string.IsNullOrEmpty(track2ContinuationToken));
425-
}
426-
427383
public static AzureStorageBlob GetAzureStorageBlob(BlobItem blobItem, BlobContainerClient track2container, AzureStorageContext context, string continuationToken = null, BlobClientOptions options = null)
428384
{
429385
BlobBaseClient blobClient = Util.GetTrack2BlobClient(track2container, blobItem.Name, context, blobItem.VersionId, blobItem.IsLatestVersion, blobItem.Snapshot, options, blobItem.Properties.BlobType);

src/Storage/Storage/Blob/Cmdlet/GetAzureStorageBlobByTag.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public GetAzureStorageBlobByTagCommand(IStorageBlobManagement channel)
9090
/// <summary>
9191
/// list blobs by blob Tag
9292
/// </summary>
93-
internal async Task ListBlobsByTag(long taskId, IStorageBlobManagement localChannel, string tagFilterSqlExpression)
93+
internal void ListBlobsByTag(IStorageBlobManagement localChannel, string tagFilterSqlExpression)
9494
{
9595

9696
BlobServiceClient blobServiceClient = Util.GetTrack2BlobServiceClient(localChannel.StorageContext, ClientOptions);
@@ -106,16 +106,16 @@ internal async Task ListBlobsByTag(long taskId, IStorageBlobManagement localChan
106106
{
107107
requestCount = Math.Min(listCount, MaxListCount);
108108
realListCount = 0;
109-
IAsyncEnumerator<Page<TaggedBlobItem>> enumerator = blobServiceClient.FindBlobsByTagsAsync(tagFilterSqlExpression, CmdletCancellationToken)
109+
IEnumerator<Page<TaggedBlobItem>> enumerator = blobServiceClient.FindBlobsByTags(tagFilterSqlExpression, CmdletCancellationToken)
110110
.AsPages(track2ContinuationToken, requestCount)
111-
.GetAsyncEnumerator();
111+
.GetEnumerator();
112112

113113
Page<TaggedBlobItem> page;
114-
await enumerator.MoveNextAsync().ConfigureAwait(false);
114+
enumerator.MoveNext();
115115
page = enumerator.Current;
116116
foreach (TaggedBlobItem item in page.Values)
117117
{
118-
OutputStream.WriteObject(taskId, new AzureStorageBlob(item, Channel.StorageContext, page.ContinuationToken, ClientOptions, this.GetBlobProperty.IsPresent));
118+
WriteObject(new AzureStorageBlob(item, Channel.StorageContext, page.ContinuationToken, ClientOptions, this.GetBlobProperty.IsPresent));
119119
realListCount++;
120120
}
121121
track2ContinuationToken = page.ContinuationToken;
@@ -133,12 +133,9 @@ internal async Task ListBlobsByTag(long taskId, IStorageBlobManagement localChan
133133
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
134134
public override void ExecuteCmdlet()
135135
{
136-
Func<long, Task> taskGenerator = null;
137136
IStorageBlobManagement localChannel = Channel;
138137

139-
taskGenerator = (taskId) => ListBlobsByTag(taskId, localChannel, this.TagFilterSqlExpression);
140-
141-
RunTask(taskGenerator);
138+
ListBlobsByTag(localChannel, this.TagFilterSqlExpression);
142139
}
143140
}
144141
}

0 commit comments

Comments
 (0)