diff --git a/sdk/identity/Azure.Identity/src/CredentialPipeline.cs b/sdk/identity/Azure.Identity/src/CredentialPipeline.cs index 00185b267a726..85f092312b991 100644 --- a/sdk/identity/Azure.Identity/src/CredentialPipeline.cs +++ b/sdk/identity/Azure.Identity/src/CredentialPipeline.cs @@ -17,19 +17,13 @@ internal class CredentialPipeline private CredentialPipeline(TokenCredentialOptions options) { - AuthorityHost = options.AuthorityHost; - HttpPipeline = HttpPipelineBuilder.Build(options, Array.Empty(), Array.Empty(), new CredentialResponseClassifier()); - Diagnostics = new ClientDiagnostics(options); } - public CredentialPipeline(Uri authorityHost, HttpPipeline httpPipeline, ClientDiagnostics diagnostics) + public CredentialPipeline(HttpPipeline httpPipeline, ClientDiagnostics diagnostics) { - AuthorityHost = authorityHost; - HttpPipeline = httpPipeline; - Diagnostics = diagnostics; } @@ -38,8 +32,6 @@ public static CredentialPipeline GetInstance(TokenCredentialOptions options) return options is null ? s_singleton.Value : new CredentialPipeline(options); } - public Uri AuthorityHost { get; } - public HttpPipeline HttpPipeline { get; } public ClientDiagnostics Diagnostics { get; } diff --git a/sdk/identity/Azure.Identity/src/Credentials/DeviceCodeCredential.cs b/sdk/identity/Azure.Identity/src/Credentials/DeviceCodeCredential.cs index c16c78ab838d9..641e144a34e93 100644 --- a/sdk/identity/Azure.Identity/src/Credentials/DeviceCodeCredential.cs +++ b/sdk/identity/Azure.Identity/src/Credentials/DeviceCodeCredential.cs @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using Azure.Core; -using Azure.Core.Pipeline; -using Microsoft.Identity.Client; using System; using System.ComponentModel; using System.Threading; using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.Pipeline; +using Microsoft.Identity.Client; namespace Azure.Identity { @@ -25,6 +25,7 @@ public class DeviceCodeCredential : TokenCredential internal AuthenticationRecord Record { get; private set; } internal Func DeviceCodeCallback { get; } internal CredentialPipeline Pipeline { get; } + internal string DefaultScope { get; } private const string AuthenticationRequiredMessage = "Interactive authentication is needed to acquire token. Call Authenticate to initiate the device code authentication."; private const string NoDefaultScopeMessage = "Authenticating in this environment requires specifying a TokenRequestContext."; @@ -66,8 +67,8 @@ public DeviceCodeCredential(Func device /// The client id of the application to which the users will authenticate /// The client options for the newly created DeviceCodeCredential [EditorBrowsable(EditorBrowsableState.Never)] - public DeviceCodeCredential(Func deviceCodeCallback, string tenantId, string clientId, TokenCredentialOptions options = default) - : this(deviceCodeCallback, Validations.ValidateTenantId(tenantId, nameof(tenantId), allowNull:true), clientId, options, null) + public DeviceCodeCredential(Func deviceCodeCallback, string tenantId, string clientId, TokenCredentialOptions options = default) + : this(deviceCodeCallback, Validations.ValidateTenantId(tenantId, nameof(tenantId), allowNull: true), clientId, options, null) { } @@ -80,18 +81,18 @@ internal DeviceCodeCredential(Func devi { Argument.AssertNotNull(clientId, nameof(clientId)); Argument.AssertNotNull(deviceCodeCallback, nameof(deviceCodeCallback)); - _tenantId = tenantId; ClientId = clientId; DeviceCodeCallback = deviceCodeCallback; DisableAutomaticAuthentication = (options as DeviceCodeCredentialOptions)?.DisableAutomaticAuthentication ?? false; Record = (options as DeviceCodeCredentialOptions)?.AuthenticationRecord; Pipeline = pipeline ?? CredentialPipeline.GetInstance(options); + DefaultScope = AzureAuthorityHosts.GetDefaultScope(options?.AuthorityHost ?? AzureAuthorityHosts.GetDefault()); Client = client ?? new MsalPublicClient( Pipeline, tenantId, ClientId, - AzureAuthorityHosts.GetDeviceCodeRedirectUri(Pipeline.AuthorityHost).AbsoluteUri, + AzureAuthorityHosts.GetDeviceCodeRedirectUri(options?.AuthorityHost ?? AzureAuthorityHosts.GetDefault()).AbsoluteUri, options); AdditionallyAllowedTenantIds = TenantIdResolver.ResolveAddionallyAllowedTenantIds(options?.AdditionallyAllowedTenantsCore); } @@ -103,10 +104,13 @@ internal DeviceCodeCredential(Func devi /// The result of the authentication request, containing the acquired , and the which can be used to silently authenticate the account. public virtual AuthenticationRecord Authenticate(CancellationToken cancellationToken = default) { - // get the default scope for the authority, throw if no default scope exists - string defaultScope = AzureAuthorityHosts.GetDefaultScope(Pipeline.AuthorityHost) ?? throw new CredentialUnavailableException(NoDefaultScopeMessage); + // throw if no default scope exists + if (DefaultScope == null) + { + throw new CredentialUnavailableException(NoDefaultScopeMessage); + } - return Authenticate(new TokenRequestContext(new string[] { defaultScope }), cancellationToken); + return Authenticate(new TokenRequestContext(new string[] { DefaultScope }), cancellationToken); } /// @@ -116,10 +120,13 @@ public virtual AuthenticationRecord Authenticate(CancellationToken cancellationT /// The which can be used to silently authenticate the account on future execution of credentials using the same persisted token cache. public virtual async Task AuthenticateAsync(CancellationToken cancellationToken = default) { - // get the default scope for the authority, throw if no default scope exists - string defaultScope = AzureAuthorityHosts.GetDefaultScope(Pipeline.AuthorityHost) ?? throw new CredentialUnavailableException(NoDefaultScopeMessage); + // throw if no default scope exists + if (DefaultScope == null) + { + throw new CredentialUnavailableException(NoDefaultScopeMessage); + } - return await AuthenticateAsync(new TokenRequestContext(new string[] { defaultScope }), cancellationToken).ConfigureAwait(false); + return await AuthenticateAsync(new TokenRequestContext(new string[] { DefaultScope }), cancellationToken).ConfigureAwait(false); } /// diff --git a/sdk/identity/Azure.Identity/src/Credentials/InteractiveBrowserCredential.cs b/sdk/identity/Azure.Identity/src/Credentials/InteractiveBrowserCredential.cs index e06c4d4e9878e..f83147cafaebe 100644 --- a/sdk/identity/Azure.Identity/src/Credentials/InteractiveBrowserCredential.cs +++ b/sdk/identity/Azure.Identity/src/Credentials/InteractiveBrowserCredential.cs @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using Azure.Core; -using Azure.Core.Pipeline; -using Microsoft.Identity.Client; using System; using System.ComponentModel; using System.Threading; using System.Threading.Tasks; +using Azure.Core; +using Azure.Core.Pipeline; +using Microsoft.Identity.Client; namespace Azure.Identity { @@ -25,6 +25,7 @@ public class InteractiveBrowserCredential : TokenCredential internal CredentialPipeline Pipeline { get; } internal bool DisableAutomaticAuthentication { get; } internal AuthenticationRecord Record { get; private set; } + internal string DefaultScope { get; } private const string AuthenticationRequiredMessage = "Interactive authentication is needed to acquire token. Call Authenticate to interactively authenticate."; private const string NoDefaultScopeMessage = "Authenticating in this environment requires specifying a TokenRequestContext."; @@ -83,6 +84,7 @@ internal InteractiveBrowserCredential(string tenantId, string clientId, TokenCre Pipeline = pipeline ?? CredentialPipeline.GetInstance(options); LoginHint = (options as InteractiveBrowserCredentialOptions)?.LoginHint; var redirectUrl = (options as InteractiveBrowserCredentialOptions)?.RedirectUri?.AbsoluteUri ?? Constants.DefaultRedirectUrl; + DefaultScope = AzureAuthorityHosts.GetDefaultScope(options?.AuthorityHost ?? AzureAuthorityHosts.GetDefault()); Client = client ?? new MsalPublicClient(Pipeline, tenantId, clientId, redirectUrl, options); AdditionallyAllowedTenantIds = TenantIdResolver.ResolveAddionallyAllowedTenantIds(options?.AdditionallyAllowedTenantsCore); Record = (options as InteractiveBrowserCredentialOptions)?.AuthenticationRecord; @@ -95,10 +97,12 @@ internal InteractiveBrowserCredential(string tenantId, string clientId, TokenCre /// The result of the authentication request, containing the acquired , and the which can be used to silently authenticate the account. public virtual AuthenticationRecord Authenticate(CancellationToken cancellationToken = default) { - // get the default scope for the authority, throw if no default scope exists - string defaultScope = AzureAuthorityHosts.GetDefaultScope(Pipeline.AuthorityHost) ?? throw new CredentialUnavailableException(NoDefaultScopeMessage); - - return Authenticate(new TokenRequestContext(new[] { defaultScope }), cancellationToken); + // throw if no default scope exists + if (DefaultScope == null) + { + throw new CredentialUnavailableException(NoDefaultScopeMessage); + } + return Authenticate(new TokenRequestContext(new[] { DefaultScope }), cancellationToken); } /// @@ -108,10 +112,12 @@ public virtual AuthenticationRecord Authenticate(CancellationToken cancellationT /// The result of the authentication request, containing the acquired , and the which can be used to silently authenticate the account. public virtual async Task AuthenticateAsync(CancellationToken cancellationToken = default) { - // get the default scope for the authority, throw if no default scope exists - string defaultScope = AzureAuthorityHosts.GetDefaultScope(Pipeline.AuthorityHost) ?? throw new CredentialUnavailableException(NoDefaultScopeMessage); - - return await AuthenticateAsync(new TokenRequestContext(new string[] { defaultScope }), cancellationToken).ConfigureAwait(false); + // throw if no default scope exists + if (DefaultScope == null) + { + throw new CredentialUnavailableException(NoDefaultScopeMessage); + } + return await AuthenticateAsync(new TokenRequestContext(new string[] { DefaultScope }), cancellationToken).ConfigureAwait(false); } /// diff --git a/sdk/identity/Azure.Identity/src/Credentials/ManagedIdentityCredential.cs b/sdk/identity/Azure.Identity/src/Credentials/ManagedIdentityCredential.cs index cca3aaeeb2665..c30e17bc78cc4 100644 --- a/sdk/identity/Azure.Identity/src/Credentials/ManagedIdentityCredential.cs +++ b/sdk/identity/Azure.Identity/src/Credentials/ManagedIdentityCredential.cs @@ -45,7 +45,7 @@ protected ManagedIdentityCredential() /// /// Options to configure the management of the requests sent to the Azure Active Directory service. public ManagedIdentityCredential(string clientId = null, TokenCredentialOptions options = null) - : this(clientId, CredentialPipeline.GetInstance(options)) + : this(new ManagedIdentityClient(new ManagedIdentityClientOptions { ClientId = clientId, Pipeline = CredentialPipeline.GetInstance(options), Options = options })) { _logAccountDetails = options?.Diagnostics?.IsAccountIdentifierLoggingEnabled ?? false; } @@ -59,21 +59,20 @@ public ManagedIdentityCredential(string clientId = null, TokenCredentialOptions /// /// Options to configure the management of the requests sent to the Azure Active Directory service. public ManagedIdentityCredential(ResourceIdentifier resourceId, TokenCredentialOptions options = null) - : this( - new ManagedIdentityClient(new ManagedIdentityClientOptions { ResourceIdentifier = resourceId, Pipeline = CredentialPipeline.GetInstance(options) })) + : this(new ManagedIdentityClient(new ManagedIdentityClientOptions { ResourceIdentifier = resourceId, Pipeline = CredentialPipeline.GetInstance(options), Options = options })) { _logAccountDetails = options?.Diagnostics?.IsAccountIdentifierLoggingEnabled ?? false; _clientId = resourceId.ToString(); } - internal ManagedIdentityCredential(string clientId, CredentialPipeline pipeline, bool preserveTransport = false) - : this(new ManagedIdentityClient(new ManagedIdentityClientOptions { Pipeline = pipeline, ClientId = clientId, PreserveTransport = preserveTransport })) + internal ManagedIdentityCredential(string clientId, CredentialPipeline pipeline, TokenCredentialOptions options = null, bool preserveTransport = false) + : this(new ManagedIdentityClient(new ManagedIdentityClientOptions { Pipeline = pipeline, ClientId = clientId, PreserveTransport = preserveTransport, Options = options })) { _clientId = clientId; } - internal ManagedIdentityCredential(ResourceIdentifier resourceId, CredentialPipeline pipeline, bool preserveTransport = false) - : this(new ManagedIdentityClient(new ManagedIdentityClientOptions{Pipeline = pipeline, ResourceIdentifier = resourceId, PreserveTransport = preserveTransport})) + internal ManagedIdentityCredential(ResourceIdentifier resourceId, CredentialPipeline pipeline, TokenCredentialOptions options, bool preserveTransport = false) + : this(new ManagedIdentityClient(new ManagedIdentityClientOptions{Pipeline = pipeline, ResourceIdentifier = resourceId, PreserveTransport = preserveTransport, Options = options })) { _clientId = resourceId.ToString(); } diff --git a/sdk/identity/Azure.Identity/src/Credentials/UsernamePasswordCredential.cs b/sdk/identity/Azure.Identity/src/Credentials/UsernamePasswordCredential.cs index cb57a736e809b..2ecf14fde076b 100644 --- a/sdk/identity/Azure.Identity/src/Credentials/UsernamePasswordCredential.cs +++ b/sdk/identity/Azure.Identity/src/Credentials/UsernamePasswordCredential.cs @@ -29,6 +29,7 @@ public class UsernamePasswordCredential : TokenCredential private readonly string _tenantId; internal string[] AdditionallyAllowedTenantIds { get; } internal MsalPublicClient Client { get; } + internal string DefaultScope { get; } /// /// Protected constructor for mocking @@ -92,6 +93,7 @@ internal UsernamePasswordCredential( _password = password; _clientId = clientId; _pipeline = pipeline ?? CredentialPipeline.GetInstance(options); + DefaultScope = AzureAuthorityHosts.GetDefaultScope(options?.AuthorityHost ?? AzureAuthorityHosts.GetDefault()); Client = client ?? new MsalPublicClient(_pipeline, tenantId, clientId, null, options); AdditionallyAllowedTenantIds = TenantIdResolver.ResolveAddionallyAllowedTenantIds(options?.AdditionallyAllowedTenantsCore); @@ -104,10 +106,13 @@ internal UsernamePasswordCredential( /// The of the authenticated account. public virtual AuthenticationRecord Authenticate(CancellationToken cancellationToken = default) { - // get the default scope for the authority, throw if no default scope exists - string defaultScope = AzureAuthorityHosts.GetDefaultScope(_pipeline.AuthorityHost) ?? throw new CredentialUnavailableException(NoDefaultScopeMessage); + // throw if no default scope exists + if (DefaultScope == null) + { + throw new CredentialUnavailableException(NoDefaultScopeMessage); + } - return Authenticate(new TokenRequestContext(new string[] { defaultScope }), cancellationToken); + return Authenticate(new TokenRequestContext(new string[] { DefaultScope }), cancellationToken); } /// @@ -117,10 +122,13 @@ public virtual AuthenticationRecord Authenticate(CancellationToken cancellationT /// The of the authenticated account. public virtual async Task AuthenticateAsync(CancellationToken cancellationToken = default) { - // get the default scope for the authority, throw if no default scope exists - string defaultScope = AzureAuthorityHosts.GetDefaultScope(_pipeline.AuthorityHost) ?? throw new CredentialUnavailableException(NoDefaultScopeMessage); + // throw if no default scope exists + if (DefaultScope == null) + { + throw new CredentialUnavailableException(NoDefaultScopeMessage); + } - return await AuthenticateAsync(new TokenRequestContext(new string[] { defaultScope }), cancellationToken).ConfigureAwait(false); + return await AuthenticateAsync(new TokenRequestContext(new string[] { DefaultScope }), cancellationToken).ConfigureAwait(false); } /// diff --git a/sdk/identity/Azure.Identity/src/MsalClientBase.cs b/sdk/identity/Azure.Identity/src/MsalClientBase.cs index 3886ccabf3eab..da395f252921e 100644 --- a/sdk/identity/Azure.Identity/src/MsalClientBase.cs +++ b/sdk/identity/Azure.Identity/src/MsalClientBase.cs @@ -32,7 +32,8 @@ protected MsalClientBase(CredentialPipeline pipeline, string tenantId, string cl // variable rather than in code. In this case we need to validate the endpoint before we use it. However, we can't validate in // CredentialPipeline as this is also used by the ManagedIdentityCredential which allows non TLS endpoints. For this reason // we validate here as all other credentials will create an MSAL client. - Validations.ValidateAuthorityHost(pipeline?.AuthorityHost); + Validations.ValidateAuthorityHost(options?.AuthorityHost); + AuthorityHost = options?.AuthorityHost ?? AzureAuthorityHosts.GetDefault(); _logAccountDetails = options?.Diagnostics?.IsAccountIdentifierLoggingEnabled ?? false; DisableInstanceDiscovery = options is ISupportsDisableInstanceDiscovery supportsDisableInstanceDiscovery && supportsDisableInstanceDiscovery.DisableInstanceDiscovery; ITokenCacheOptions cacheOptions = options as ITokenCacheOptions; @@ -50,6 +51,8 @@ protected MsalClientBase(CredentialPipeline pipeline, string tenantId, string cl internal TokenCache TokenCache { get; } + internal Uri AuthorityHost { get; } + protected internal CredentialPipeline Pipeline { get; } protected abstract ValueTask CreateClientAsync(bool async, CancellationToken cancellationToken); diff --git a/sdk/identity/Azure.Identity/src/MsalConfidentialClient.cs b/sdk/identity/Azure.Identity/src/MsalConfidentialClient.cs index 19d986749d0f2..04bf0ea54462c 100644 --- a/sdk/identity/Azure.Identity/src/MsalConfidentialClient.cs +++ b/sdk/identity/Azure.Identity/src/MsalConfidentialClient.cs @@ -18,7 +18,6 @@ internal class MsalConfidentialClient : MsalClientBase _assertionCallback; private readonly Func> _asyncAssertionCallback; private readonly Func> _appTokenProviderCallback; - private readonly Uri _authority; internal string RedirectUrl { get; } @@ -58,7 +57,6 @@ public MsalConfidentialClient(CredentialPipeline pipeline, string tenantId, stri : base(pipeline, tenantId, clientId, options) { _appTokenProviderCallback = appTokenProviderCallback; - _authority = options?.AuthorityHost ?? AzureAuthorityHosts.AzurePublicCloud; } internal string RegionalAuthority { get; } = EnvironmentVariables.AzureRegionalAuthorityName; @@ -74,12 +72,12 @@ protected override async ValueTask CreateClientA if (_appTokenProviderCallback != null) { confClientBuilder.WithAppTokenProvider(_appTokenProviderCallback) - .WithAuthority(_authority.AbsoluteUri, TenantId, false) + .WithAuthority(AuthorityHost.AbsoluteUri, TenantId, false) .WithInstanceDiscovery(false); } else { - confClientBuilder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, TenantId); + confClientBuilder.WithAuthority(AuthorityHost.AbsoluteUri, TenantId); if (DisableInstanceDiscovery) { confClientBuilder.WithInstanceDiscovery(false); @@ -146,7 +144,7 @@ public virtual async ValueTask AcquireTokenForClientCoreAs if (!string.IsNullOrEmpty(tenantId)) { - builder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, tenantId); + builder.WithAuthority(AuthorityHost.AbsoluteUri, tenantId); } return await builder .ExecuteAsync(async, cancellationToken) @@ -179,7 +177,7 @@ public virtual async ValueTask AcquireTokenSilentCoreAsync var builder = client.AcquireTokenSilent(scopes, account); if (!string.IsNullOrEmpty(tenantId)) { - builder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, tenantId); + builder.WithAuthority(AuthorityHost.AbsoluteUri, tenantId); } return await builder .ExecuteAsync(async, cancellationToken) @@ -213,7 +211,7 @@ public virtual async ValueTask AcquireTokenByAuthorization if (!string.IsNullOrEmpty(tenantId)) { - builder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, tenantId); + builder.WithAuthority(AuthorityHost.AbsoluteUri, tenantId); } return await builder .ExecuteAsync(async, cancellationToken) @@ -247,7 +245,7 @@ public virtual async ValueTask AcquireTokenOnBehalfOfCoreA if (!string.IsNullOrEmpty(tenantId)) { - builder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, tenantId); + builder.WithAuthority(AuthorityHost.AbsoluteUri, tenantId); } return await builder .ExecuteAsync(async, cancellationToken) diff --git a/sdk/identity/Azure.Identity/src/MsalPublicClient.cs b/sdk/identity/Azure.Identity/src/MsalPublicClient.cs index f58dd3c4a08f2..0f5a155cf664c 100644 --- a/sdk/identity/Azure.Identity/src/MsalPublicClient.cs +++ b/sdk/identity/Azure.Identity/src/MsalPublicClient.cs @@ -38,8 +38,7 @@ protected override ValueTask CreateClientAsync(bool as protected virtual ValueTask CreateClientCoreAsync(string[] clientCapabilities, bool async, CancellationToken cancellationToken) { - var authorityHost = Pipeline.AuthorityHost; - var authorityUri = new UriBuilder(authorityHost.Scheme, authorityHost.Host, authorityHost.Port, TenantId ?? Constants.OrganizationsTenantId).Uri; + var authorityUri = new UriBuilder(AuthorityHost.Scheme, AuthorityHost.Host, AuthorityHost.Port, TenantId ?? Constants.OrganizationsTenantId).Uri; PublicClientApplicationBuilder pubAppBuilder = PublicClientApplicationBuilder .Create(ClientId) @@ -96,7 +95,7 @@ protected virtual async ValueTask AcquireTokenSilentCoreAs if (tenantId != null) { - builder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, tenantId); + builder.WithAuthority(AuthorityHost.AbsoluteUri, tenantId); } return await builder @@ -119,7 +118,7 @@ protected virtual async ValueTask AcquireTokenSilentCoreAs // otherwise we should authenticate with the tenant specified by the authentication record since that's the tenant the // user authenticated to originally. return await client.AcquireTokenSilent(scopes, (AuthenticationAccount)record) - .WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, TenantId ?? record.TenantId) + .WithAuthority(AuthorityHost.AbsoluteUri, TenantId ?? record.TenantId) .WithClaims(claims) .ExecuteAsync(async, cancellationToken) .ConfigureAwait(false); @@ -170,7 +169,7 @@ protected virtual async ValueTask AcquireTokenInteractiveC } if (tenantId != null) { - builder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, tenantId); + builder.WithAuthority(AuthorityHost.AbsoluteUri, tenantId); } return await builder .ExecuteAsync(async, cancellationToken) @@ -192,7 +191,7 @@ protected virtual async ValueTask AcquireTokenByUsernamePa .WithClaims(claims); if (!string.IsNullOrEmpty(tenantId)) { - builder.WithAuthority(Pipeline.AuthorityHost.AbsoluteUri, tenantId); + builder.WithAuthority(AuthorityHost.AbsoluteUri, tenantId); } return await builder.ExecuteAsync(async, cancellationToken) .ConfigureAwait(false); diff --git a/sdk/identity/Azure.Identity/src/ServiceFabricManagedIdentitySource.cs b/sdk/identity/Azure.Identity/src/ServiceFabricManagedIdentitySource.cs index 3851a1e8c0775..83f8290d08c33 100644 --- a/sdk/identity/Azure.Identity/src/ServiceFabricManagedIdentitySource.cs +++ b/sdk/identity/Azure.Identity/src/ServiceFabricManagedIdentitySource.cs @@ -42,7 +42,7 @@ public static ManagedIdentitySource TryCreate(ManagedIdentityClientOptions optio { var customSslHttpPipline = HttpPipelineBuilder.Build(new TokenCredentialOptions { Transport = GetServiceFabricMITransport() }); - pipeline = new CredentialPipeline(pipeline.AuthorityHost, customSslHttpPipline, pipeline.Diagnostics); + pipeline = new CredentialPipeline(customSslHttpPipline, pipeline.Diagnostics); } return new ServiceFabricManagedIdentitySource(pipeline, endpointUri, identityHeader, options); diff --git a/sdk/identity/Azure.Identity/tests/AzureIdentityEventSourceTests.cs b/sdk/identity/Azure.Identity/tests/AzureIdentityEventSourceTests.cs index c6aebf278b267..d3c9cb0b7a2fa 100644 --- a/sdk/identity/Azure.Identity/tests/AzureIdentityEventSourceTests.cs +++ b/sdk/identity/Azure.Identity/tests/AzureIdentityEventSourceTests.cs @@ -161,7 +161,7 @@ public async Task ValidateDeviceCodeCredentialFailedEvents() SilentAuthFactory = (_, _) => throw new MockClientException(expExMessage) }; - var credential = InstrumentClient(new DeviceCodeCredential((_, _) => { return Task.CompletedTask; }, default, Guid.NewGuid().ToString(), default, default, mockMsalClient)); + var credential = InstrumentClient(new DeviceCodeCredential((_, _) => { return Task.CompletedTask; }, default, Guid.NewGuid().ToString(), new(), default, mockMsalClient)); var method = "DeviceCodeCredential.GetToken"; diff --git a/sdk/identity/Azure.Identity/tests/ChainedTokenCredentialTests.cs b/sdk/identity/Azure.Identity/tests/ChainedTokenCredentialTests.cs index 17da4d86304f3..881d87190a291 100644 --- a/sdk/identity/Azure.Identity/tests/ChainedTokenCredentialTests.cs +++ b/sdk/identity/Azure.Identity/tests/ChainedTokenCredentialTests.cs @@ -27,7 +27,7 @@ public class MockException : Exception [SetUp] public void Setup() { - _pipeline = new CredentialPipeline(new Uri("https://a.b.com"), new HttpPipeline(new MockTransport()), new ClientDiagnostics(new TokenCredentialOptions())); + _pipeline = new CredentialPipeline(new HttpPipeline(new MockTransport()), new ClientDiagnostics(new TokenCredentialOptions() { AuthorityHost = new Uri("https://a.b.com")})); } public class SimpleMockTokenCredential : TokenCredential diff --git a/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs b/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs index e72ae5a1f1cdb..846d09945f91f 100644 --- a/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs +++ b/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs @@ -225,15 +225,18 @@ public async Task SendCertificateChain([Values(true, false)] bool usePemFile, [V var certificatePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data", "cert.pfx"); var certificatePathPem = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data", "cert.pem"); var mockCert = new X509Certificate2(certificatePath); - options = new ClientCertificateCredentialOptions(); + options = new ClientCertificateCredentialOptions + { + AuthorityHost = new Uri("https://localhost") + }; ((ClientCertificateCredentialOptions)options).SendCertificateChain = sendCertChain; ClientCertificateCredential credential = InstrumentClient( usePemFile ? new ClientCertificateCredential(TenantId, ClientId, certificatePathPem, default, options, - new CredentialPipeline(new Uri("https://localhost"), _pipeline, new ClientDiagnostics(options)), null) + new CredentialPipeline(_pipeline, new ClientDiagnostics(options)), null) : new ClientCertificateCredential(TenantId, ClientId, mockCert, options, - new CredentialPipeline(new Uri("https://localhost"), _pipeline, new ClientDiagnostics(options)), null) + new CredentialPipeline(_pipeline, new ClientDiagnostics(options)), null) ); var token = await credential.GetTokenAsync(context); diff --git a/sdk/identity/Azure.Identity/tests/DeviceCodeCredentialCtorTests.cs b/sdk/identity/Azure.Identity/tests/DeviceCodeCredentialCtorTests.cs index 2c63681000dca..30257ac718e78 100644 --- a/sdk/identity/Azure.Identity/tests/DeviceCodeCredentialCtorTests.cs +++ b/sdk/identity/Azure.Identity/tests/DeviceCodeCredentialCtorTests.cs @@ -118,7 +118,6 @@ public void AssertOptionsHonored(DeviceCodeCredentialOptions options, DeviceCode { Assert.AreEqual(options.ClientId, credential.ClientId); Assert.AreEqual(options.TenantId, credential.Client.TenantId); - Assert.AreEqual(options.AuthorityHost, credential.Pipeline.AuthorityHost); Assert.AreEqual(options.DisableAutomaticAuthentication, credential.DisableAutomaticAuthentication); Assert.AreEqual(options.AuthenticationRecord, credential.Record); diff --git a/sdk/identity/Azure.Identity/tests/InteractiveBrowserCredentialCtorTests.cs b/sdk/identity/Azure.Identity/tests/InteractiveBrowserCredentialCtorTests.cs index 0fada1c1f468d..988ba12e255fb 100644 --- a/sdk/identity/Azure.Identity/tests/InteractiveBrowserCredentialCtorTests.cs +++ b/sdk/identity/Azure.Identity/tests/InteractiveBrowserCredentialCtorTests.cs @@ -113,7 +113,6 @@ public void AssertOptionsHonored(InteractiveBrowserCredentialOptions options, In { Assert.AreEqual(options.ClientId, credential.ClientId); Assert.AreEqual(options.TenantId, credential.Client.TenantId); - Assert.AreEqual(options.AuthorityHost, credential.Pipeline.AuthorityHost); Assert.AreEqual(options.DisableAutomaticAuthentication, credential.DisableAutomaticAuthentication); Assert.AreEqual(options.AuthenticationRecord, credential.Record); diff --git a/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialImdsLiveTests.cs b/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialImdsLiveTests.cs index 6c7e512592103..961bf5cc0213c 100644 --- a/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialImdsLiveTests.cs +++ b/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialImdsLiveTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Azure.Security.KeyVault.Secrets; +using Microsoft.CodeAnalysis; using NUnit.Framework; namespace Azure.Identity.Tests @@ -73,11 +74,7 @@ public async Task ValidateImdsUserAssignedIdentity() private ManagedIdentityCredential CreateManagedIdentityCredential(string clientId = null, TokenCredentialOptions options = null) { options = InstrumentClientOptions(options ?? new TokenCredentialOptions()); - - var pipeline = CredentialPipeline.GetInstance(options); - - var cred = new ManagedIdentityCredential(new ManagedIdentityClient(pipeline, clientId)); - + var cred = new ManagedIdentityCredential(clientId, options); return cred; } } diff --git a/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialTests.cs b/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialTests.cs index 9401753977704..0014d13a78dfb 100644 --- a/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialTests.cs +++ b/sdk/identity/Azure.Identity/tests/ManagedIdentityCredentialTests.cs @@ -113,11 +113,9 @@ public async Task VerifyImdsRequestWithClientIdAndRegionalAuthorityNameMockAsync var mockTransport = new MockTransport(req => CreateMockResponse(200, ExpectedToken)); var options = new TokenCredentialOptions() { Transport = mockTransport }; - var pipeline = CredentialPipeline.GetInstance(options); - - ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential("mock-client-id", pipeline)); + ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential("mock-client-id", options)); - AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)); + AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default, tenantId: Guid.NewGuid().ToString())); Assert.AreEqual(ExpectedToken, actualToken.Token); } @@ -132,16 +130,9 @@ public async Task VerifyImdsRequestWithClientIdAndNonPubCloudMockAsync(Uri autho var response = CreateMockResponse(200, ExpectedToken); var mockTransport = new MockTransport(response); var options = new TokenCredentialOptions() { Transport = mockTransport, AuthorityHost = authority }; - //var pipeline = CredentialPipeline.GetInstance(options); - var _pipeline = new HttpPipeline(mockTransport); - var pipeline = new CredentialPipeline(authority, _pipeline, new ClientDiagnostics(options)); - - ManagedIdentityCredential credential = InstrumentClient( - new ManagedIdentityCredential( - new ManagedIdentityClient( - new ManagedIdentityClientOptions { Pipeline = pipeline, ClientId = "mock-client-id", Options = options }))); + ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential("mock-client-id", options)); - AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)); + AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default, tenantId: Guid.NewGuid().ToString())); Assert.AreEqual(ExpectedToken, actualToken.Token); @@ -167,9 +158,8 @@ public async Task VerifyImdsRequestWithResourceIdMockAsync() var response = CreateMockResponse(200, ExpectedToken); var mockTransport = new MockTransport(response); var options = new TokenCredentialOptions { Transport = mockTransport }; - var pipeline = CredentialPipeline.GetInstance(options); - ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential(new ResourceIdentifier(_expectedResourceId), pipeline)); + ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential(new ResourceIdentifier(_expectedResourceId), options)); AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)); @@ -216,9 +206,9 @@ public async Task VerifyServiceFabricRequestWithResourceIdMockAsync(string clien ManagedIdentityCredential credential = (clientId, includeResourceIdentifier) switch { - (Item1: null, Item2: true) => InstrumentClient(new ManagedIdentityCredential(new ResourceIdentifier(_expectedResourceId), pipeline, true)), - (Item1: not null, Item2: false) => InstrumentClient(new ManagedIdentityCredential(clientId, pipeline, true)), - _ => InstrumentClient(new ManagedIdentityCredential(clientId: null, pipeline, true)) + (Item1: null, Item2: true) => InstrumentClient(new ManagedIdentityCredential(new ResourceIdentifier(_expectedResourceId), pipeline, options, preserveTransport: true)), + (Item1: not null, Item2: false) => InstrumentClient(new ManagedIdentityCredential(clientId, pipeline, options, preserveTransport: true)), + _ => InstrumentClient(new ManagedIdentityCredential(clientId: null, pipeline, options, preserveTransport: true)) }; AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)); @@ -324,9 +314,8 @@ public async Task VerifyIMDSRequestWithPodIdentityEnvVarResourceIdMockAsync() var response = CreateMockResponse(200, ExpectedToken); var mockTransport = new MockTransport(response); var options = new TokenCredentialOptions() { Transport = mockTransport }; - var pipeline = CredentialPipeline.GetInstance(options); - ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential(new ResourceIdentifier(_expectedResourceId), pipeline)); + ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential(new ResourceIdentifier(_expectedResourceId), options)); AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)); diff --git a/sdk/identity/Azure.Identity/tests/Mock/TestDefaultAzureCredentialFactory.cs b/sdk/identity/Azure.Identity/tests/Mock/TestDefaultAzureCredentialFactory.cs index cd828f48eceb7..baef556203629 100644 --- a/sdk/identity/Azure.Identity/tests/Mock/TestDefaultAzureCredentialFactory.cs +++ b/sdk/identity/Azure.Identity/tests/Mock/TestDefaultAzureCredentialFactory.cs @@ -25,7 +25,7 @@ public override TokenCredential CreateEnvironmentCredential() => new EnvironmentCredential(Pipeline, Options); public override TokenCredential CreateManagedIdentityCredential() - => new ManagedIdentityCredential(new ManagedIdentityClient(Pipeline, Options.ManagedIdentityClientId)); + => new ManagedIdentityCredential(Options.ManagedIdentityClientId, Pipeline, Options); public override TokenCredential CreateSharedTokenCacheCredential() => new SharedTokenCacheCredential(Options.SharedTokenCacheTenantId, Options.SharedTokenCacheUsername, Options, Pipeline); diff --git a/sdk/identity/Azure.Identity/tests/MsalClientBaseTests.cs b/sdk/identity/Azure.Identity/tests/MsalClientBaseTests.cs index f2b710899c526..8ee1f105a7a8e 100644 --- a/sdk/identity/Azure.Identity/tests/MsalClientBaseTests.cs +++ b/sdk/identity/Azure.Identity/tests/MsalClientBaseTests.cs @@ -36,13 +36,13 @@ public void LogPiiIsEnforcedPerInstance([Values(true, false)] bool logPii) EventLevel.Verbose); var client_1 = new MockMsalClient( - new CredentialPipeline(new Uri("https://w.com"), new HttpPipeline(new MockTransport()), new ClientDiagnostics(Moq.Mock.Of())), + new CredentialPipeline(new HttpPipeline(new MockTransport()), new ClientDiagnostics(Moq.Mock.Of())), "tenant", "client", new InteractiveBrowserCredentialOptions(){ IsLoggingPIIEnabled = logPii }); var client_2 = new MockMsalClient( - new CredentialPipeline(new Uri("https://w.com"), new HttpPipeline(new MockTransport()), new ClientDiagnostics(Moq.Mock.Of())), + new CredentialPipeline(new HttpPipeline(new MockTransport()), new ClientDiagnostics(Moq.Mock.Of())), "tenant", "client", new InteractiveBrowserCredentialOptions(){ IsLoggingPIIEnabled = false }); // never log PII diff --git a/sdk/identity/Azure.Identity/tests/OnBehalfOfCredentialTests.cs b/sdk/identity/Azure.Identity/tests/OnBehalfOfCredentialTests.cs index 306774dbbbd51..e314820233807 100644 --- a/sdk/identity/Azure.Identity/tests/OnBehalfOfCredentialTests.cs +++ b/sdk/identity/Azure.Identity/tests/OnBehalfOfCredentialTests.cs @@ -140,7 +140,10 @@ public async Task SendCertificateChain([Values(true, false)] bool sendCertChain) var certificatePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data", "cert.pfx"); var mockCert = new X509Certificate2(certificatePath); - options = new OnBehalfOfCredentialOptions(); + options = new OnBehalfOfCredentialOptions + { + AuthorityHost = new Uri("https://localhost") + }; ((OnBehalfOfCredentialOptions)options).SendCertificateChain = sendCertChain; OnBehalfOfCredential client = InstrumentClient( new OnBehalfOfCredential( @@ -149,7 +152,7 @@ public async Task SendCertificateChain([Values(true, false)] bool sendCertChain) mockCert, expectedUserAssertion, options as OnBehalfOfCredentialOptions, - new CredentialPipeline(new Uri("https://localhost"), _pipeline, new ClientDiagnostics(options)), + new CredentialPipeline(_pipeline, new ClientDiagnostics(options)), null)); var token = await client.GetTokenAsync(new TokenRequestContext(MockScopes.Default), default);