Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
45 changes: 45 additions & 0 deletions LibsAndSamples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Identity.Test.E2E.MSI", "tests\Microsoft.Identity.Test.E2e\Microsoft.Identity.Test.E2E.MSI.csproj", "{97995B86-AA0F-3AF9-DA40-85A6263E4391}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MacMauiAppWithBroker", "tests\devapps\MacMauiAppWithBroker\MacMauiAppWithBroker.csproj", "{AEF6BB00-931F-4638-955D-24D735625C34}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MacConsoleAppWithBroker", "tests\devapps\MacConsoleAppWithBroker\MacConsoleAppWithBroker.csproj", "{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug + MobileApps|Any CPU = Debug + MobileApps|Any CPU
Expand Down Expand Up @@ -1866,6 +1868,48 @@ Global
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|x64.Build.0 = Release|Any CPU
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|x86.ActiveCfg = Release|Any CPU
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|x86.Build.0 = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|Any CPU.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|Any CPU.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|ARM.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|ARM.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|ARM64.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|ARM64.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|iPhone.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|iPhone.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|iPhoneSimulator.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|x64.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|x64.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|x86.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug + MobileApps|x86.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|ARM.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|ARM64.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|iPhone.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|x64.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|x64.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|x86.ActiveCfg = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Debug|x86.Build.0 = Debug|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|Any CPU.Build.0 = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|ARM.ActiveCfg = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|ARM.Build.0 = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|ARM64.ActiveCfg = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|ARM64.Build.0 = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|iPhone.ActiveCfg = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|iPhone.Build.0 = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|x64.ActiveCfg = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|x64.Build.0 = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|x86.ActiveCfg = Release|Any CPU
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1921,6 +1965,7 @@ Global
{DA9C3258-DEF6-7794-9762-20CF7B826839} = {BCAEE9AE-8D3E-4C77-A2E4-134E1552D5F8}
{97995B86-AA0F-3AF9-DA40-85A6263E4391} = {9B0B5396-4D95-4C15-82ED-DC22B5A3123F}
{AEF6BB00-931F-4638-955D-24D735625C34} = {34BE693E-3496-45A4-B1D2-D3A0E068EEDB}
{DBD18BC8-72E4-47D4-BD79-8DEBD9F2C0D0} = {34BE693E-3496-45A4-B1D2-D3A0E068EEDB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {020399A9-DC27-4B82-9CAA-EF488665AC27}
Expand Down
85 changes: 69 additions & 16 deletions src/client/Microsoft.Identity.Client.Broker/RuntimeBroker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,16 +186,34 @@ public async Task<MsalTokenResponse> AcquireTokenInteractiveAsync(
{
if (readAccountResult.IsSuccess)
{
using (var result = await s_lazyCore.Value.AcquireTokenInteractivelyAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
readAccountResult.Account,
cancellationToken).ConfigureAwait(false))
if (DesktopOsHelper.IsMac())
{
AuthResult result = null;
await MacMainThreadScheduler.Instance.RunOnMainThreadAsync(async () =>
{
result = await s_lazyCore.Value.AcquireTokenInteractivelyAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
readAccountResult.Account,
cancellationToken).ConfigureAwait(false);
}).ConfigureAwait(false);
var errorMessage = "Could not acquire token interactively.";
msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
}
else // Non macOS
{
using (var result = await s_lazyCore.Value.AcquireTokenInteractivelyAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
readAccountResult.Account,
cancellationToken).ConfigureAwait(false))
{
var errorMessage = "Could not acquire token interactively.";
msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
}
}
}
else
{
Expand Down Expand Up @@ -238,16 +256,34 @@ private async Task<MsalTokenResponse> SignInInteractivelyAsync(
string loginHint = authenticationRequestParameters.LoginHint ?? authenticationRequestParameters?.Account?.Username;
_logger?.Verbose(() => "[RuntimeBroker] AcquireTokenInteractive - login hint provided? " + !string.IsNullOrEmpty(loginHint));

using (var result = await s_lazyCore.Value.SignInInteractivelyAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
loginHint,
cancellationToken).ConfigureAwait(false))
if (DesktopOsHelper.IsMac())
{
AuthResult result = null;
await MacMainThreadScheduler.Instance.RunOnMainThreadAsync(async () =>
{
result = await s_lazyCore.Value.SignInInteractivelyAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
loginHint,
cancellationToken).ConfigureAwait(false);
}).ConfigureAwait(false);
var errorMessage = "Could not sign in interactively.";
msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
}
else // Non macOS
{
using (var result = await s_lazyCore.Value.SignInInteractivelyAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
loginHint,
cancellationToken).ConfigureAwait(true))
{
var errorMessage = "Could not sign in interactively.";
msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
}
}
}

return msalTokenResponse;
Expand All @@ -268,14 +304,31 @@ private async Task<MsalTokenResponse> AcquireTokenInteractiveDefaultUserAsync(
_brokerOptions,
_logger))
{
using (NativeInterop.AuthResult result = await s_lazyCore.Value.SignInAsync(
if (DesktopOsHelper.IsMac())
{
AuthResult result = null;
await MacMainThreadScheduler.Instance.RunOnMainThreadAsync(async () =>
{
result = await s_lazyCore.Value.SignInAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
cancellationToken).ConfigureAwait(false);
}).ConfigureAwait(false);
var errorMessage = "Could not sign in interactively with the default OS account.";
msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
}
else // Non macOS
{
using (NativeInterop.AuthResult result = await s_lazyCore.Value.SignInAsync(
_parentHandle,
authParams,
authenticationRequestParameters.CorrelationId.ToString("D"),
cancellationToken).ConfigureAwait(false))
{
var errorMessage = "Could not sign in interactively with the default OS account.";
msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
{
var errorMessage = "Could not sign in interactively with the default OS account.";
msalTokenResponse = WamAdapters.HandleResponse(result, authenticationRequestParameters, _logger, errorMessage);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.Identity.Client.Instance.Discovery;
using Microsoft.Identity.Client.Instance.Validation;
using Microsoft.Identity.Client.Internal;
using Microsoft.Identity.Client.PlatformsCommon.Shared;
using Microsoft.Identity.Client.Utils;
using static Microsoft.Identity.Client.AuthorityInfo;

Expand Down Expand Up @@ -47,7 +48,15 @@ public async Task<InstanceDiscoveryMetadataEntry> GetInstanceDiscoveryEntryAsync

public async Task RunInstanceDiscoveryAndValidationAsync()
{
if (!_instanceDiscoveryAndValidationExecuted)
if (DesktopOsHelper.IsMac() && _requestContext.ServiceBundle.Config.IsBrokerEnabled)
{
// On macOS, for broker flows we should avoid authority validation. Internally, we should avoid any network requests to prevent context switch.
// Interactive calls need to happen in the main thread, making network calls will switch to another thread and not easy to go back.
_metadata = _requestContext.ServiceBundle.InstanceDiscoveryManager.GetMetadataEntryAvoidNetwork(
_initialAuthority.AuthorityInfo,
_requestContext);
}
else if (!_instanceDiscoveryAndValidationExecuted)
{
// This will make a network call unless instance discovery is cached, but this OK
// GetAccounts and AcquireTokenSilent do not need this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace Microsoft.Identity.Client.Instance.Discovery
/// </summary>
internal interface IInstanceDiscoveryManager
{
InstanceDiscoveryMetadataEntry GetMetadataEntryAvoidNetwork(
AuthorityInfo authorityInfo,
RequestContext requestContext);
Task<InstanceDiscoveryMetadataEntry> GetMetadataEntryTryAvoidNetworkAsync(
AuthorityInfo authorityinfo,
IEnumerable<string> existingEnvironmentsInCache,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,25 @@ public InstanceDiscoveryManager(
}
}

public InstanceDiscoveryMetadataEntry GetMetadataEntryAvoidNetwork(
AuthorityInfo authorityInfo,
RequestContext requestContext)
{
string environment = authorityInfo.Host;
InstanceDiscoveryMetadataEntry entry = null;
if (requestContext.ServiceBundle.Config.IsInstanceDiscoveryEnabled)
{
entry = _networkCacheMetadataProvider.GetMetadata(environment, requestContext.Logger) ??
_knownMetadataProvider.GetMetadata(environment, null, requestContext.Logger);
}
if (entry == null)
{
requestContext.Logger.Info(() => $"Skipping Instance discovery for {authorityInfo.AuthorityType} authority and use single authority.");
entry = CreateEntryForSingleAuthority(authorityInfo.CanonicalAuthority);
}
return entry;
}

public async Task<InstanceDiscoveryMetadataEntry> GetMetadataEntryTryAvoidNetworkAsync(
AuthorityInfo authorityInfo,
IEnumerable<string> existingEnvironmentsInCache,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
using Microsoft.Identity.Client.Instance;
using Microsoft.Identity.Client.Internal.Broker;
using Microsoft.Identity.Client.OAuth2;
using Microsoft.Identity.Client.PlatformsCommon.Shared;
using Microsoft.Identity.Client.UI;
using Microsoft.Identity.Client.Utils;

namespace Microsoft.Identity.Client.Internal.Requests
{
Expand Down Expand Up @@ -63,8 +65,45 @@ protected override async Task<AuthenticationResult> ExecuteAsync(
{
await ResolveAuthorityAsync().ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
MsalTokenResponse tokenResponse = await GetTokenResponseAsync(cancellationToken)
.ConfigureAwait(false);
MsalTokenResponse tokenResponse = null;
if (DesktopOsHelper.IsMac() && ServiceBundle.Config.IsBrokerEnabled)
{
var macMainThreadScheduler = MacMainThreadScheduler.Instance;
if (!macMainThreadScheduler.IsCurrentlyOnMainThread)
{
throw new MsalClientException(
MsalError.WamUiThread,
"Interactive requests with mac broker enabled must be executed on the main thread on macOS.");
}
bool messageLoopStarted = macMainThreadScheduler.IsRunning;
var tcs = new TaskCompletionSource<MsalTokenResponse>();
_ = Task.Run(async () =>
{
try
{
MsalTokenResponse response = await GetTokenResponseAsync(cancellationToken).ConfigureAwait(false);
tcs.SetResult(response);
}
catch (Exception ex)
{
_logger.Error($"Error in background GetTokenResponseAsync: {ex}");
tcs.SetException(ex);
}
finally
{
if (!messageLoopStarted)
macMainThreadScheduler.Stop();
}
});
if (!messageLoopStarted)
macMainThreadScheduler.StartMessageLoop();
tokenResponse = await tcs.Task.ConfigureAwait(false);
}
else
{
tokenResponse = await GetTokenResponseAsync(cancellationToken)
.ConfigureAwait(false);
}
return await CacheTokenResponseAndCreateAuthenticationResultAsync(tokenResponse)
.ConfigureAwait(false);
}
Expand Down
Loading