diff --git a/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenByAuthorizationCodeParameterBuilder.cs b/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenByAuthorizationCodeParameterBuilder.cs index 5f7c44b469..5846ea5faf 100644 --- a/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenByAuthorizationCodeParameterBuilder.cs +++ b/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenByAuthorizationCodeParameterBuilder.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Microsoft.Identity.Client.Advanced; +using Microsoft.Identity.Client.Extensibility; using Microsoft.Identity.Client.ApiConfig.Executors; using Microsoft.Identity.Client.ApiConfig.Parameters; using Microsoft.Identity.Client.Internal; diff --git a/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenOnBehalfOfParameterBuilder.cs b/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenOnBehalfOfParameterBuilder.cs index 4589d3079b..d52e68e998 100644 --- a/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenOnBehalfOfParameterBuilder.cs +++ b/src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenOnBehalfOfParameterBuilder.cs @@ -1,87 +1,87 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Identity.Client.Advanced; -using Microsoft.Identity.Client.ApiConfig.Executors; -using Microsoft.Identity.Client.ApiConfig.Parameters; -using Microsoft.Identity.Client.Internal; -using Microsoft.Identity.Client.TelemetryCore.Internal.Events; -using Microsoft.Identity.Client.Utils; - -namespace Microsoft.Identity.Client +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Identity.Client.Extensibility; +using Microsoft.Identity.Client.ApiConfig.Executors; +using Microsoft.Identity.Client.ApiConfig.Parameters; +using Microsoft.Identity.Client.Internal; +using Microsoft.Identity.Client.TelemetryCore.Internal.Events; +using Microsoft.Identity.Client.Utils; + +namespace Microsoft.Identity.Client { - /// - /// Builder for AcquireTokenOnBehalfOf (OBO flow) - /// See https://aka.ms/msal-net-on-behalf-of - /// -#if !SUPPORTS_CONFIDENTIAL_CLIENT - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] // hide confidential client on mobile -#endif - public sealed class AcquireTokenOnBehalfOfParameterBuilder : - AbstractConfidentialClientAcquireTokenParameterBuilder - { - internal AcquireTokenOnBehalfOfParameters Parameters { get; } = new AcquireTokenOnBehalfOfParameters(); - - /// - internal AcquireTokenOnBehalfOfParameterBuilder(IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor) - : base(confidentialClientApplicationExecutor) - { - } - - internal static AcquireTokenOnBehalfOfParameterBuilder Create( - IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor, - IEnumerable scopes, - UserAssertion userAssertion) - { - return new AcquireTokenOnBehalfOfParameterBuilder(confidentialClientApplicationExecutor) - .WithScopes(scopes) - .WithUserAssertion(userAssertion); - } - - internal static AcquireTokenOnBehalfOfParameterBuilder Create( - IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor, - IEnumerable scopes, - UserAssertion userAssertion, - string cacheKey) - { - return new AcquireTokenOnBehalfOfParameterBuilder(confidentialClientApplicationExecutor) - .WithScopes(scopes) - .WithUserAssertion(userAssertion) - .WithCacheKey(cacheKey); - } - - internal static AcquireTokenOnBehalfOfParameterBuilder Create( - IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor, - IEnumerable scopes, - string cacheKey) - { - return new AcquireTokenOnBehalfOfParameterBuilder(confidentialClientApplicationExecutor) - .WithScopes(scopes) - .WithCacheKey(cacheKey); - } - - private AcquireTokenOnBehalfOfParameterBuilder WithUserAssertion(UserAssertion userAssertion) - { - Parameters.UserAssertion = userAssertion; - return this; - } - - /// - /// Specifies a key by which to look up the token in the cache instead of searching by an assertion. - /// - /// Key by which to look up the token in the cache - /// A builder enabling you to add optional parameters before executing the token request - private AcquireTokenOnBehalfOfParameterBuilder WithCacheKey(string cacheKey) - { - Parameters.LongRunningOboCacheKey = cacheKey ?? throw new ArgumentNullException(nameof(cacheKey)); - return this; - } - - /// + /// + /// Builder for AcquireTokenOnBehalfOf (OBO flow) + /// See https://aka.ms/msal-net-on-behalf-of + /// +#if !SUPPORTS_CONFIDENTIAL_CLIENT + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] // hide confidential client on mobile +#endif + public sealed class AcquireTokenOnBehalfOfParameterBuilder : + AbstractConfidentialClientAcquireTokenParameterBuilder + { + internal AcquireTokenOnBehalfOfParameters Parameters { get; } = new AcquireTokenOnBehalfOfParameters(); + + /// + internal AcquireTokenOnBehalfOfParameterBuilder(IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor) + : base(confidentialClientApplicationExecutor) + { + } + + internal static AcquireTokenOnBehalfOfParameterBuilder Create( + IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor, + IEnumerable scopes, + UserAssertion userAssertion) + { + return new AcquireTokenOnBehalfOfParameterBuilder(confidentialClientApplicationExecutor) + .WithScopes(scopes) + .WithUserAssertion(userAssertion); + } + + internal static AcquireTokenOnBehalfOfParameterBuilder Create( + IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor, + IEnumerable scopes, + UserAssertion userAssertion, + string cacheKey) + { + return new AcquireTokenOnBehalfOfParameterBuilder(confidentialClientApplicationExecutor) + .WithScopes(scopes) + .WithUserAssertion(userAssertion) + .WithCacheKey(cacheKey); + } + + internal static AcquireTokenOnBehalfOfParameterBuilder Create( + IConfidentialClientApplicationExecutor confidentialClientApplicationExecutor, + IEnumerable scopes, + string cacheKey) + { + return new AcquireTokenOnBehalfOfParameterBuilder(confidentialClientApplicationExecutor) + .WithScopes(scopes) + .WithCacheKey(cacheKey); + } + + private AcquireTokenOnBehalfOfParameterBuilder WithUserAssertion(UserAssertion userAssertion) + { + Parameters.UserAssertion = userAssertion; + return this; + } + + /// + /// Specifies a key by which to look up the token in the cache instead of searching by an assertion. + /// + /// Key by which to look up the token in the cache + /// A builder enabling you to add optional parameters before executing the token request + private AcquireTokenOnBehalfOfParameterBuilder WithCacheKey(string cacheKey) + { + Parameters.LongRunningOboCacheKey = cacheKey ?? throw new ArgumentNullException(nameof(cacheKey)); + return this; + } + + /// /// Applicable to first-party applications only, this method also allows to specify /// if the x5c claim should be sent to Azure AD. /// Sending the x5c enables application developers to achieve easy certificate roll-over in Azure AD: @@ -89,96 +89,96 @@ private AcquireTokenOnBehalfOfParameterBuilder WithCacheKey(string cacheKey) /// so that Azure AD can use it to validate the subject name based on a trusted issuer policy. /// This saves the application admin from the need to explicitly manage the certificate rollover /// (either via portal or PowerShell/CLI operation). For details see https://aka.ms/msal-net-sni - /// - /// true if the x5c should be sent. Otherwise false. - /// The default is false - /// The builder to chain the .With methods - public AcquireTokenOnBehalfOfParameterBuilder WithSendX5C(bool withSendX5C) - { + /// + /// true if the x5c should be sent. Otherwise false. + /// The default is false + /// The builder to chain the .With methods + public AcquireTokenOnBehalfOfParameterBuilder WithSendX5C(bool withSendX5C) + { Parameters.SendX5C = withSendX5C; - return this; - } - - /// + return this; + } + + /// /// Specifies if the client application should ignore access tokens when reading the token cache. /// New tokens will still be written to the token cache. /// By default the token is taken from the the user token cache (forceRefresh=false) - /// - /// If true, ignore any access token in the user token cache - /// and attempt to acquire new access token using the refresh token for the account + /// + /// If true, ignore any access token in the user token cache + /// and attempt to acquire new access token using the refresh token for the account /// if one is available. The default is false - /// The builder to chain the .With methods + /// The builder to chain the .With methods /// /// Do not use this flag except in well understood cases. Identity Providers will throttle clients that issue too many similar token requests. /// - public AcquireTokenOnBehalfOfParameterBuilder WithForceRefresh(bool forceRefresh) - { - Parameters.ForceRefresh = forceRefresh; - return this; - } - - /// - /// To help with resiliency, the AAD backup authentication system operates as an AAD backup. - /// This will provide the AAD backup authentication system with a routing hint to help improve performance during authentication. - /// - /// GUID which is unique to the user, parsed from the client_info. - /// GUID format of the tenant ID, parsed from the client_info. - /// The builder to chain the .With methods - public AcquireTokenOnBehalfOfParameterBuilder WithCcsRoutingHint(string userObjectIdentifier, string tenantIdentifier) - { - if (string.IsNullOrEmpty(userObjectIdentifier) || string.IsNullOrEmpty(tenantIdentifier)) - { - return this; - } - - var ccsRoutingHeader = new Dictionary() - { - { Constants.CcsRoutingHintHeader, CoreHelpers.GetCcsClientInfoHint(userObjectIdentifier, tenantIdentifier) } - }; - - this.WithExtraHttpHeaders(ccsRoutingHeader); - return this; - } - - /// - /// To help with resiliency, the AAD backup authentication system operates as an AAD backup. - /// This will provide the AAD backup authentication system with a routing hint to help improve performance during authentication. - /// - /// Identifier of the user. Generally in UserPrincipalName (UPN) format, e.g. john.doe@contoso.com - /// The builder to chain the .With methods - public AcquireTokenOnBehalfOfParameterBuilder WithCcsRoutingHint(string userName) - { - if (string.IsNullOrEmpty(userName)) - { - return this; - } - - var ccsRoutingHeader = new Dictionary() - { - { Constants.CcsRoutingHintHeader, CoreHelpers.GetCcsUpnHint(userName) } - }; - - this.WithExtraHttpHeaders(ccsRoutingHeader); - return this; + public AcquireTokenOnBehalfOfParameterBuilder WithForceRefresh(bool forceRefresh) + { + Parameters.ForceRefresh = forceRefresh; + return this; + } + + /// + /// To help with resiliency, the AAD backup authentication system operates as an AAD backup. + /// This will provide the AAD backup authentication system with a routing hint to help improve performance during authentication. + /// + /// GUID which is unique to the user, parsed from the client_info. + /// GUID format of the tenant ID, parsed from the client_info. + /// The builder to chain the .With methods + public AcquireTokenOnBehalfOfParameterBuilder WithCcsRoutingHint(string userObjectIdentifier, string tenantIdentifier) + { + if (string.IsNullOrEmpty(userObjectIdentifier) || string.IsNullOrEmpty(tenantIdentifier)) + { + return this; + } + + var ccsRoutingHeader = new Dictionary() + { + { Constants.CcsRoutingHintHeader, CoreHelpers.GetCcsClientInfoHint(userObjectIdentifier, tenantIdentifier) } + }; + + this.WithExtraHttpHeaders(ccsRoutingHeader); + return this; + } + + /// + /// To help with resiliency, the AAD backup authentication system operates as an AAD backup. + /// This will provide the AAD backup authentication system with a routing hint to help improve performance during authentication. + /// + /// Identifier of the user. Generally in UserPrincipalName (UPN) format, e.g. john.doe@contoso.com + /// The builder to chain the .With methods + public AcquireTokenOnBehalfOfParameterBuilder WithCcsRoutingHint(string userName) + { + if (string.IsNullOrEmpty(userName)) + { + return this; + } + + var ccsRoutingHeader = new Dictionary() + { + { Constants.CcsRoutingHintHeader, CoreHelpers.GetCcsUpnHint(userName) } + }; + + this.WithExtraHttpHeaders(ccsRoutingHeader); + return this; } - - /// - internal override Task ExecuteInternalAsync(CancellationToken cancellationToken) - { - return ConfidentialClientApplicationExecutor.ExecuteAsync(CommonParameters, Parameters, cancellationToken); - } - + + /// + internal override Task ExecuteInternalAsync(CancellationToken cancellationToken) + { + return ConfidentialClientApplicationExecutor.ExecuteAsync(CommonParameters, Parameters, cancellationToken); + } + /// protected override void Validate() { base.Validate(); - if (Parameters.SendX5C == null) - { - Parameters.SendX5C = this.ServiceBundle.Config?.SendX5C ?? false; + if (Parameters.SendX5C == null) + { + Parameters.SendX5C = this.ServiceBundle.Config?.SendX5C ?? false; } - } - /// - internal override ApiEvent.ApiIds CalculateApiEventId() + } + /// + internal override ApiEvent.ApiIds CalculateApiEventId() { if (string.IsNullOrEmpty(Parameters.LongRunningOboCacheKey)) { @@ -194,7 +194,7 @@ internal override ApiEvent.ApiIds CalculateApiEventId() { return ApiEvent.ApiIds.AcquireTokenInLongRunningObo; } - } - } - } -} + } + } + } +} diff --git a/src/client/Microsoft.Identity.Client/AppConfig/BaseAbstractApplicationBuilder.cs b/src/client/Microsoft.Identity.Client/AppConfig/BaseAbstractApplicationBuilder.cs index b60ae2dbe0..bf083a6101 100644 --- a/src/client/Microsoft.Identity.Client/AppConfig/BaseAbstractApplicationBuilder.cs +++ b/src/client/Microsoft.Identity.Client/AppConfig/BaseAbstractApplicationBuilder.cs @@ -169,6 +169,7 @@ public T WithLogging( /// is thrown if the loggingCallback /// was already set on the application builder by calling /// + [EditorBrowsable(EditorBrowsableState.Never)] public T WithDebugLoggingCallback( LogLevel logLevel = LogLevel.Info, bool enablePiiLogging = false, @@ -218,6 +219,7 @@ public T WithExperimentalFeatures(bool enableExperimentalFeatures = true) /// /// The name of the SDK API for telemetry purposes. /// + [EditorBrowsable(EditorBrowsableState.Never)] public T WithClientName(string clientName) { Config.ClientName = GetValueIfNotEmpty(Config.ClientName, clientName); @@ -229,6 +231,7 @@ public T WithClientName(string clientName) /// /// The version of the calling SDK for telemetry purposes. /// + [EditorBrowsable(EditorBrowsableState.Never)] public T WithClientVersion(string clientVersion) { Config.ClientVersion = GetValueIfNotEmpty(Config.ClientVersion, clientVersion); diff --git a/src/client/Microsoft.Identity.Client/Extensibility/AcquireTokenParameterBuilderExtensions.cs b/src/client/Microsoft.Identity.Client/Extensibility/AcquireTokenParameterBuilderExtensions.cs index 198b135712..1d318946f8 100644 --- a/src/client/Microsoft.Identity.Client/Extensibility/AcquireTokenParameterBuilderExtensions.cs +++ b/src/client/Microsoft.Identity.Client/Extensibility/AcquireTokenParameterBuilderExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; namespace Microsoft.Identity.Client.Advanced { @@ -16,13 +17,14 @@ public static class AcquireTokenParameterBuilderExtensions /// Parameter builder for a acquiring tokens. /// additional Http Headers to add to the token request. /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This method has been moved to the Microsoft.Identity.Client.Extensibility namespace", false)] public static T WithExtraHttpHeaders( this AbstractAcquireTokenParameterBuilder builder, IDictionary extraHttpHeaders) where T : AbstractAcquireTokenParameterBuilder { - builder.CommonParameters.ExtraHttpHeaders = extraHttpHeaders; - return (T)builder; + return Microsoft.Identity.Client.Extensibility.AcquireTokenParameterBuilderExtensions.WithExtraHttpHeaders(builder, extraHttpHeaders); } } } @@ -42,10 +44,9 @@ public static T WithExtraHttpHeaders( this AbstractAcquireTokenParameterBuilder builder, IDictionary extraHttpHeaders) where T : AbstractAcquireTokenParameterBuilder - { - // Delegate to the Advanced implementation to keep a single source of truth. - return Advanced.AcquireTokenParameterBuilderExtensions - .WithExtraHttpHeaders(builder, extraHttpHeaders); + { + builder.CommonParameters.ExtraHttpHeaders = extraHttpHeaders; + return (T)builder; } } } diff --git a/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/ConfidentialClientAuthorizationTests.cs b/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/ConfidentialClientAuthorizationTests.cs index 41e4226364..35a9bba068 100644 --- a/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/ConfidentialClientAuthorizationTests.cs +++ b/tests/Microsoft.Identity.Test.Integration.netcore/SeleniumTests/ConfidentialClientAuthorizationTests.cs @@ -8,7 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Identity.Client; -using Microsoft.Identity.Client.Advanced; +using Microsoft.Identity.Client.Extensibility; using Microsoft.Identity.Client.UI; using Microsoft.Identity.Test.Common; using Microsoft.Identity.Test.Common.Core.Helpers; diff --git a/tests/Microsoft.Identity.Test.Unit/PublicApiTests/PublicClientApplicationTests.cs b/tests/Microsoft.Identity.Test.Unit/PublicApiTests/PublicClientApplicationTests.cs index 7cc3cfd0dd..e152def6a5 100644 --- a/tests/Microsoft.Identity.Test.Unit/PublicApiTests/PublicClientApplicationTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/PublicApiTests/PublicClientApplicationTests.cs @@ -10,7 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Identity.Client; -using Microsoft.Identity.Client.Advanced; +using Microsoft.Identity.Client.Extensibility; #if NET8_0_OR_GREATER using Microsoft.Identity.Client.Broker; #endif