Skip to content

Commit e67b2df

Browse files
author
Lei Jin
committed
Enabled globally disabling instance discovery before token acquisition
Fix #22535
1 parent a6c112f commit e67b2df

15 files changed

+109
-18
lines changed

src/Accounts/Accounts/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
-->
2020

2121
## Upcoming Release
22+
* Enabled globally disabling instance discovery before token acquisition [#22535].
2223
* Added `AsSecureString` to `Get-AzAccessToken` to convert the returned token to SecureString [#24190].
2324
* Upgraded Azure.Core to 1.37.0.
2425

src/Accounts/Authentication/Authentication/Parameters/AuthenticationParameters.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
// ----------------------------------------------------------------------------------
1414

1515
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
16+
using Microsoft.Azure.Commands.Common.Exceptions;
17+
using Microsoft.Azure.Commands.Shared.Config;
18+
using Microsoft.Azure.PowerShell.Common.Config;
1619

1720
namespace Microsoft.Azure.Commands.Common.Authentication
1821
{
@@ -28,6 +31,8 @@ public abstract class AuthenticationParameters
2831

2932
public string ResourceId { get; set; }
3033

34+
public bool? DisableInstanceDiscovery { get; set; } = null;
35+
3136
public AuthenticationParameters(
3237
PowerShellTokenCacheProvider tokenCacheProvider,
3338
IAzureEnvironment environment,
@@ -41,6 +46,17 @@ public AuthenticationParameters(
4146
TokenCache = tokenCache;
4247
TenantId = tenantId;
4348
ResourceId = resourceId;
49+
try
50+
{
51+
if (AzureSession.Instance.TryGetComponent<IConfigManager>(nameof(IConfigManager), out var config))
52+
{
53+
DisableInstanceDiscovery = config.GetConfigValue<bool>(ConfigKeys.DisableInstanceDiscovery);
54+
}
55+
}
56+
catch(AzPSArgumentException)
57+
{
58+
DisableInstanceDiscovery = null;
59+
}
4460
}
4561
}
4662
}

src/Accounts/Authentication/Config/ConfigInitializer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ private void RegisterConfigs(IConfigManager configManager)
232232
false,
233233
"AZURE_CLIENTS_SHOW_SECRETS_WARNING",
234234
new[] { AppliesTo.Az }));
235+
configManager.RegisterConfig(new DisableInstanceDiscoveryConfig());
235236
}
236237
}
237238
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
16+
using Microsoft.Azure.Commands.Common.Authentication.Properties;
17+
using Microsoft.Azure.Commands.ResourceManager.Common;
18+
using Microsoft.Azure.Commands.Shared.Config;
19+
using Microsoft.Azure.PowerShell.Common.Config;
20+
using System;
21+
using System.Collections.Generic;
22+
23+
namespace Microsoft.Azure.Commands.Common.Authentication.Config.Definitions
24+
{
25+
/// <summary>
26+
/// Definition of the config to control whether login by WAM (web account manager) or not.
27+
/// </summary>
28+
internal class DisableInstanceDiscoveryConfig : TypedConfig<bool>
29+
{
30+
public override object DefaultValue => false; // Opt-in. Will change to opt-out.
31+
32+
public override string Key => ConfigKeys.DisableInstanceDiscovery;
33+
34+
public override string HelpMessage => Resources.HelpMessageOfDisableInstanceDiscovery;
35+
36+
public override IReadOnlyCollection<AppliesTo> CanApplyTo => new[] { AppliesTo.Az };
37+
38+
protected override void ApplyTyped(bool value)
39+
{
40+
base.ApplyTyped(value);
41+
EventHandler<StreamEventArgs> writeWarningEvent;
42+
if (AzureSession.Instance.TryGetComponent(AzureRMCmdlet.WriteWarningKey, out writeWarningEvent) && value)
43+
{
44+
writeWarningEvent(this, new StreamEventArgs() { Message = Resources.DisableInstanceDiscoveryWarning });
45+
}
46+
}
47+
}
48+
}

src/Accounts/Authentication/Properties/Resources.Designer.cs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Accounts/Authentication/Properties/Resources.resx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,4 +405,10 @@
405405
<data name="HelpMessageOfDisplaySecretsWarning" xml:space="preserve">
406406
<value>When enabled, a warning message will be displayed when the cmdlet output contains secrets. Learn more at https://go.microsoft.com/fwlink/?linkid=2258844</value>
407407
</data>
408-
</root>
408+
<data name="DisableInstanceDiscoveryWarning" xml:space="preserve">
409+
<value>Set it to true to disable both instance discovery and authority validation. This functionality is intended for use in scenarios where the metadata endpoint cannot be reached, such as in private clouds or Azure Stack. It is crucial to ensure that the configured authority host is valid and trustworthy.</value>
410+
</data>
411+
<data name="HelpMessageOfDisableInstanceDiscovery" xml:space="preserve">
412+
<value>Set it to true to disable both instance discovery and authority validation. This functionality is intended for use in scenarios where the metadata endpoint cannot be reached, such as in private clouds or Azure Stack. The process of instance discovery entails retrieving authority metadata from https://login.microsoft.com/ to validate the authority. By setting this to true, the validation of the authority is disabled. As a result, it is crucial to ensure that the configured authority host is valid and trustworthy.</value>
413+
</data>
414+
</root>

src/Accounts/Authenticators/ClientAssertionAuthenticator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public override Task<IAccessToken> Authenticate(AuthenticationParameters paramet
4545
AuthorityHost = new Uri(authority),
4646
TokenCachePersistenceOptions = spParameters.TokenCacheProvider.GetTokenCachePersistenceOptions()
4747
};
48+
options.DisableInstanceDiscovery = spParameters.DisableInstanceDiscovery ?? options.DisableInstanceDiscovery;
4849
options.Diagnostics.IsTelemetryEnabled = false; // disable telemetry to avoid error thrown from Azure.Core that AssemblyInformationalVersion is null
4950
TokenCredential tokenCredential = new ClientAssertionCredential(tenantId, spParameters.ClientId, () => GetClientAssertion(spParameters), options);
5051
string parametersLog = $"- ClientId:'{spParameters.ClientId}', TenantId:'{tenantId}', ClientAssertion:'***' Scopes:'{string.Join(",", scopes)}'";

src/Accounts/Authenticators/DeviceCodeAuthenticator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public override Task<IAccessToken> Authenticate(AuthenticationParameters paramet
5353
TenantId = tenantId,
5454
TokenCachePersistenceOptions = tokenCacheProvider.GetTokenCachePersistenceOptions(),
5555
};
56+
options.DisableInstanceDiscovery = deviceCodeParameters.DisableInstanceDiscovery ?? options.DisableInstanceDiscovery;
5657
var codeCredential = new DeviceCodeCredential(options);
5758

5859
TracingAdapter.Information($"{DateTime.Now:T} - [DeviceCodeAuthenticator] Calling DeviceCodeCredential.AuthenticateAsync - TenantId:'{options.TenantId}', Scopes:'{string.Join(",", scopes)}', AuthorityHost:'{options.AuthorityHost}'");

src/Accounts/Authenticators/InteractiveUserAuthenticator.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,20 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15-
using System;
16-
using System.Diagnostics;
17-
using System.Net;
18-
using System.Net.Sockets;
19-
using System.Runtime.InteropServices;
20-
using System.Threading;
21-
using System.Threading.Tasks;
22-
2315
using Azure.Core;
2416
using Azure.Identity;
25-
using Azure.Identity.Broker;
2617

2718
using Hyak.Common;
2819

2920
using Microsoft.Azure.Commands.Common.Authentication;
3021
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
3122

23+
using System;
24+
using System.Net;
25+
using System.Net.Sockets;
26+
using System.Threading;
27+
using System.Threading.Tasks;
28+
3229
namespace Microsoft.Azure.PowerShell.Authenticators
3330
{
3431
/// <summary>
@@ -68,6 +65,7 @@ public override Task<IAccessToken> Authenticate(AuthenticationParameters paramet
6865
RedirectUri = GetReplyUrl(onPremise, interactiveParameters.PromptAction),
6966
LoginHint = interactiveParameters.UserId,
7067
};
68+
options.DisableInstanceDiscovery = interactiveParameters.DisableInstanceDiscovery ?? options.DisableInstanceDiscovery;
7169
var browserCredential = new InteractiveBrowserCredential(options);
7270

7371
TracingAdapter.Information($"{DateTime.Now:T} - [InteractiveUserAuthenticator] Calling InteractiveBrowserCredential.AuthenticateAsync with TenantId:'{options.TenantId}', Scopes:'{string.Join(",", scopes)}', AuthorityHost:'{options.AuthorityHost}', RedirectUri:'{options.RedirectUri}'");

src/Accounts/Authenticators/InteractiveWamAuthenticator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public override Task<IAccessToken> Authenticate(AuthenticationParameters paramet
6060
RedirectUri = GetReplyUrl(onPremise, interactiveParameters.PromptAction),
6161
LoginHint = interactiveParameters.UserId
6262
};
63+
options.DisableInstanceDiscovery = interactiveParameters.DisableInstanceDiscovery ?? options.DisableInstanceDiscovery;
6364
var browserCredential = new InteractiveBrowserCredential(options);
6465

6566
TracingAdapter.Information($"{DateTime.Now:T} - [InteractiveWamAuthenticator] Calling InteractiveBrowserCredential.AuthenticateAsync with TenantId:'{options.TenantId}', Scopes:'{string.Join(",", scopes)}', AuthorityHost:'{options.AuthorityHost}', RedirectUri:'{options.RedirectUri}'");

src/Accounts/Authenticators/ManagedServiceIdentityAuthenticator.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,16 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15-
using System;
16-
using System.Text.RegularExpressions;
17-
using System.Threading;
18-
using System.Threading.Tasks;
19-
2015
using Azure.Core;
21-
using Azure.Identity;
22-
23-
using Hyak.Common;
2416

2517
using Microsoft.Azure.Commands.Common.Authentication;
2618
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
2719
using Microsoft.Azure.PowerShell.Authenticators.Factories;
2820

21+
using System.Text.RegularExpressions;
22+
using System.Threading;
23+
using System.Threading.Tasks;
24+
2925
namespace Microsoft.Azure.PowerShell.Authenticators
3026
{
3127
public class ManagedServiceIdentityAuthenticator : DelegatingAuthenticator

src/Accounts/Authenticators/ServicePrincipalAuthenticator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public override Task<IAccessToken> Authenticate(AuthenticationParameters paramet
5555
SendCertificateChain = spParameters.SendCertificateChain ?? default(bool)
5656
};
5757

58+
options.DisableInstanceDiscovery = spParameters.DisableInstanceDiscovery ?? options.DisableInstanceDiscovery;
5859
TokenCredential tokenCredential = null;
5960
string parametersLog = null;
6061
if (!string.IsNullOrEmpty(spParameters.Thumbprint))

src/Accounts/Authenticators/SilentAuthenticator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ private static SharedTokenCacheCredentialOptions GetTokenCredentialOptions(Silen
6868
options.Username = silentParameters.UserId;
6969
options.AuthorityHost = new Uri(authority);
7070
options.TenantId = tenantId;
71+
options.DisableInstanceDiscovery = silentParameters.DisableInstanceDiscovery ?? options.DisableInstanceDiscovery;
7172
return options;
7273
}
7374

src/Accounts/Authenticators/UsernamePasswordAuthenticator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public override Task<IAccessToken> Authenticate(AuthenticationParameters paramet
5959
AuthorityHost = new Uri(authority),
6060
TokenCachePersistenceOptions = tokenCacheProvider.GetTokenCachePersistenceOptions()
6161
};
62+
credentialOptions.DisableInstanceDiscovery = upParameters.DisableInstanceDiscovery ?? credentialOptions.DisableInstanceDiscovery;
6263
if (upParameters.Password != null)
6364
{
6465
passwordCredential = new UsernamePasswordCredential(upParameters.UserId, upParameters.Password.ConvertToString(), tenantId, clientId, credentialOptions);

src/shared/ConfigKeys.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ internal static class ConfigKeys
3535
//Use DisableErrorRecordsPersistence as opt-out for now, will replace it with EnableErrorRecordsPersistence as opt-in at next major release (November 2023)
3636
public const string DisableErrorRecordsPersistence = "DisableErrorRecordsPersistence";
3737
public const string EnableErrorRecordsPersistence = "EnableErrorRecordsPersistence";
38+
public const string DisableInstanceDiscovery = "DisableInstanceDiscovery";
3839
public const string CheckForUpgrade = "CheckForUpgrade";
3940
public const string EnvCheckForUpgrade = "AZUREPS_CHECK_FOR_UPGRADE";
4041
public const string DisplaySecretsWarning = "DisplaySecretsWarning";

0 commit comments

Comments
 (0)