Skip to content

Commit 7e56a02

Browse files
fenggaFeng Gaogladjohn
authored
Add mac broker support and a mac sample app (#5051)
Support dotnet mac broker flow for UI based app --------- Co-authored-by: Feng Gao <[email protected]> Co-authored-by: Gladwin Johnson <[email protected]>
1 parent 3ca1ece commit 7e56a02

File tree

34 files changed

+1161
-23
lines changed

34 files changed

+1161
-23
lines changed

LibsAndSamples.sln

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "tests\devapps\WAM\N
182182
EndProject
183183
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedIdentityTokenRevocation", "tests\devapps\Managed Identity apps\ManagedIdentityTokenRevocation\ManagedIdentityTokenRevocation.csproj", "{DA9C3258-DEF6-7794-9762-20CF7B826839}"
184184
EndProject
185+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MacMauiAppWithBroker", "tests\devapps\MacMauiAppWithBroker\MacMauiAppWithBroker.csproj", "{AEF6BB00-931F-4638-955D-24D735625C34}"
186+
EndProject
185187
Global
186188
GlobalSection(SolutionConfigurationPlatforms) = preSolution
187189
Debug + MobileApps|Any CPU = Debug + MobileApps|Any CPU
@@ -1778,6 +1780,48 @@ Global
17781780
{DA9C3258-DEF6-7794-9762-20CF7B826839}.Release|x64.Build.0 = Release|Any CPU
17791781
{DA9C3258-DEF6-7794-9762-20CF7B826839}.Release|x86.ActiveCfg = Release|Any CPU
17801782
{DA9C3258-DEF6-7794-9762-20CF7B826839}.Release|x86.Build.0 = Release|Any CPU
1783+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|Any CPU.ActiveCfg = Debug|Any CPU
1784+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|Any CPU.Build.0 = Debug|Any CPU
1785+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|ARM.ActiveCfg = Debug|Any CPU
1786+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|ARM.Build.0 = Debug|Any CPU
1787+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|ARM64.ActiveCfg = Debug|Any CPU
1788+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|ARM64.Build.0 = Debug|Any CPU
1789+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|iPhone.ActiveCfg = Debug|Any CPU
1790+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|iPhone.Build.0 = Debug|Any CPU
1791+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|iPhoneSimulator.ActiveCfg = Debug|Any CPU
1792+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|iPhoneSimulator.Build.0 = Debug|Any CPU
1793+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|x64.ActiveCfg = Debug|Any CPU
1794+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|x64.Build.0 = Debug|Any CPU
1795+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|x86.ActiveCfg = Debug|Any CPU
1796+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug + MobileApps|x86.Build.0 = Debug|Any CPU
1797+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1798+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|Any CPU.Build.0 = Debug|Any CPU
1799+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|ARM.ActiveCfg = Debug|Any CPU
1800+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|ARM.Build.0 = Debug|Any CPU
1801+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|ARM64.ActiveCfg = Debug|Any CPU
1802+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|ARM64.Build.0 = Debug|Any CPU
1803+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|iPhone.ActiveCfg = Debug|Any CPU
1804+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|iPhone.Build.0 = Debug|Any CPU
1805+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
1806+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
1807+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|x64.ActiveCfg = Debug|Any CPU
1808+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|x64.Build.0 = Debug|Any CPU
1809+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|x86.ActiveCfg = Debug|Any CPU
1810+
{AEF6BB00-931F-4638-955D-24D735625C34}.Debug|x86.Build.0 = Debug|Any CPU
1811+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|Any CPU.ActiveCfg = Release|Any CPU
1812+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|Any CPU.Build.0 = Release|Any CPU
1813+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|ARM.ActiveCfg = Release|Any CPU
1814+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|ARM.Build.0 = Release|Any CPU
1815+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|ARM64.ActiveCfg = Release|Any CPU
1816+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|ARM64.Build.0 = Release|Any CPU
1817+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|iPhone.ActiveCfg = Release|Any CPU
1818+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|iPhone.Build.0 = Release|Any CPU
1819+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
1820+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
1821+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|x64.ActiveCfg = Release|Any CPU
1822+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|x64.Build.0 = Release|Any CPU
1823+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|x86.ActiveCfg = Release|Any CPU
1824+
{AEF6BB00-931F-4638-955D-24D735625C34}.Release|x86.Build.0 = Release|Any CPU
17811825
EndGlobalSection
17821826
GlobalSection(SolutionProperties) = preSolution
17831827
HideSolutionNode = FALSE
@@ -1831,6 +1875,7 @@ Global
18311875
{87679336-95BE-47E4-B42B-8F6860A0B215} = {1A37FD75-94E9-4D6F-953A-0DABBD7B49E9}
18321876
{43BCA8C7-E9F4-4067-9F54-C2127B82B5E8} = {5FAAD966-36B8-4C19-A5FA-5410DD53063D}
18331877
{DA9C3258-DEF6-7794-9762-20CF7B826839} = {BCAEE9AE-8D3E-4C77-A2E4-134E1552D5F8}
1878+
{AEF6BB00-931F-4638-955D-24D735625C34} = {34BE693E-3496-45A4-B1D2-D3A0E068EEDB}
18341879
EndGlobalSection
18351880
GlobalSection(ExtensibilityGlobals) = postSolution
18361881
SolutionGuid = {020399A9-DC27-4B82-9CAA-EF488665AC27}

src/client/Microsoft.Identity.Client.Broker/BrokerExtension.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,21 @@ public static PublicClientApplicationBuilder WithSsoPolicy(this PublicClientAppl
7171

7272
private static void AddRuntimeSupport(PublicClientApplicationBuilder builder)
7373
{
74-
if (DesktopOsHelper.IsWin10OrServerEquivalent() || DesktopOsHelper.IsLinux())
74+
if (DesktopOsHelper.IsWin10OrServerEquivalent() || DesktopOsHelper.IsLinux() || DesktopOsHelper.IsMac())
7575
{
7676
builder.Config.BrokerCreatorFunc =
7777
(uiParent, appConfig, logger) =>
7878
{
7979
logger.Info("[Runtime] Broker supported OS.");
8080
return new RuntimeBroker(uiParent, appConfig, logger);
8181
};
82-
}
82+
}
8383
else
8484
{
8585
builder.Config.BrokerCreatorFunc =
8686
(uiParent, appConfig, logger) =>
8787
{
88-
logger.Info("[RuntimeBroker] Not a Windows 10 or Server equivalent machine. Runtime broker or SsoPolicy support is not available.");
88+
logger.Warning($"[RuntimeBroker] Not available on the current platform.");
8989
return new NullBroker(logger);
9090
};
9191
}

src/client/Microsoft.Identity.Client.Broker/RuntimeBroker.cs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal class RuntimeBroker : IBroker
2727
private readonly ILoggerAdapter _logger;
2828
private readonly IntPtr _parentHandle = IntPtr.Zero;
2929
internal const string ErrorMessageSuffix = " For more details see https://aka.ms/msal-net-wam";
30-
private readonly BrokerOptions _wamOptions;
30+
private readonly BrokerOptions _brokerOptions;
3131
private static Exception s_initException;
3232

3333
// Linux broker's username password flow is via interactive calls
@@ -108,10 +108,25 @@ public RuntimeBroker(
108108
s_lazyCore.Value.EnablePii(_logger.PiiLoggingEnabled);
109109
}
110110

111-
_parentHandle = GetParentWindow(uiParent);
111+
// We need to set parent window handle for MSALRuntime on Windows.
112+
// On Windows, WAM UI correctly parented will prevent issues like WAM UI being hidden by terminal app.
113+
// The solution will be different on different platforms.
114+
if (DesktopOsHelper.IsWindows())
115+
{
116+
_parentHandle = GetParentWindow(uiParent);
117+
}
118+
else
119+
{
120+
// TODO:ADO 3055958 Parent window handle support on mac
121+
// Without setting parent window on macOS, the mac broker UI will show up in the middle
122+
// of the screen, and keep in the foreground until UI dismissed.
123+
// Technically, macOS broker only accept an objc pointer as window handle, currently we
124+
// do not know how to get such kind of pointer in MAUI. The solution is still unclear.
125+
_parentHandle = (IntPtr)1;
126+
}
112127

113128
// Broker options cannot be null
114-
_wamOptions = appConfig.BrokerOptions;
129+
_brokerOptions = appConfig.BrokerOptions;
115130
}
116131

117132
private void LogEventRaised(NativeInterop.Core sender, LogEventArgs args)
@@ -138,7 +153,7 @@ public async Task<MsalTokenResponse> AcquireTokenInteractiveAsync(
138153
Debug.Assert(s_lazyCore.Value != null, "Should not call this API if MSAL runtime init failed");
139154

140155
//need to provide a handle
141-
if (_parentHandle == IntPtr.Zero)
156+
if (DesktopOsHelper.IsWindows() && _parentHandle == IntPtr.Zero)
142157
{
143158
throw new MsalClientException(
144159
"window_handle_required",
@@ -161,7 +176,7 @@ public async Task<MsalTokenResponse> AcquireTokenInteractiveAsync(
161176
{
162177
using (var authParams = WamAdapters.GetCommonAuthParameters(
163178
authenticationRequestParameters,
164-
_wamOptions,
179+
_brokerOptions,
165180
_logger))
166181
{
167182
using (var readAccountResult = await s_lazyCore.Value.ReadAccountByIdAsync(
@@ -216,7 +231,7 @@ private async Task<MsalTokenResponse> SignInInteractivelyAsync(
216231

217232
using (var authParams = WamAdapters.GetCommonAuthParameters(
218233
authenticationRequestParameters,
219-
_wamOptions,
234+
_brokerOptions,
220235
_logger))
221236
{
222237
//Login Hint
@@ -250,7 +265,7 @@ private async Task<MsalTokenResponse> AcquireTokenInteractiveDefaultUserAsync(
250265

251266
using (var authParams = WamAdapters.GetCommonAuthParameters(
252267
authenticationRequestParameters,
253-
_wamOptions,
268+
_brokerOptions,
254269
_logger))
255270
{
256271
using (NativeInterop.AuthResult result = await s_lazyCore.Value.SignInAsync(
@@ -291,7 +306,7 @@ public async Task<MsalTokenResponse> AcquireTokenSilentAsync(
291306

292307
using (var authParams = WamAdapters.GetCommonAuthParameters(
293308
authenticationRequestParameters,
294-
_wamOptions,
309+
_brokerOptions,
295310
_logger))
296311
{
297312
using (var readAccountResult = await s_lazyCore.Value.ReadAccountByIdAsync(
@@ -354,7 +369,7 @@ public async Task<MsalTokenResponse> AcquireTokenSilentDefaultUserAsync(
354369

355370
using (var authParams = WamAdapters.GetCommonAuthParameters(
356371
authenticationRequestParameters,
357-
_wamOptions,
372+
_brokerOptions,
358373
_logger))
359374
{
360375
using (NativeInterop.AuthResult result = await s_lazyCore.Value.SignInSilentlyAsync(
@@ -399,7 +414,7 @@ public async Task<MsalTokenResponse> AcquireTokenByUsernamePasswordAsync(
399414

400415
using (AuthParameters authParams = WamAdapters.GetCommonAuthParameters(
401416
authenticationRequestParameters,
402-
_wamOptions,
417+
_brokerOptions,
403418
_logger))
404419
{
405420
authParams.Properties["MSALRuntime_Username"] = acquireTokenByUsernamePasswordParameters.Username;
@@ -499,7 +514,7 @@ public async Task<IReadOnlyList<IAccount>> GetAccountsAsync(
499514
ICacheSessionManager cacheSessionManager,
500515
IInstanceDiscoveryManager instanceDiscoveryManager)
501516
{
502-
if (!_wamOptions.ListOperatingSystemAccounts)
517+
if (!_brokerOptions.ListOperatingSystemAccounts)
503518
{
504519
_logger.Info("[RuntimeBroker] ListWindowsWorkAndSchoolAccounts option was not enabled.");
505520
return Array.Empty<IAccount>();
@@ -608,7 +623,7 @@ public void HandleInstallUrl(string appLink)
608623

609624
public bool IsBrokerInstalledAndInvokable(AuthorityType authorityType)
610625
{
611-
if (!DesktopOsHelper.IsWin10OrServerEquivalent() && !DesktopOsHelper.IsLinux())
626+
if (!DesktopOsHelper.IsWin10OrServerEquivalent() && !DesktopOsHelper.IsLinux() && !DesktopOsHelper.IsMac())
612627
{
613628
_logger?.Warning("[RuntimeBroker] Not a supported operating system. WAM broker is not available. ");
614629
return false;

src/client/Microsoft.Identity.Client/ApiConfig/BrokerOptions.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ public enum OperatingSystems
3333
/// Use broker on Linux
3434
/// </summary>
3535
Linux = 0b_0000_0010, // 2
36+
/// <summary>
37+
/// Use broker on OSX
38+
/// </summary>
39+
OSX = 0b_0000_0100, // 4
3640
}
3741

3842
/// <summary>
@@ -75,9 +79,9 @@ internal static BrokerOptions CreateFromWindowsOptions(WindowsBrokerOptions winO
7579
public bool MsaPassthrough { get; set; } = false;
7680

7781
/// <summary>
78-
/// Currently only supported on Windows and Linux
82+
/// Currently supported on Windows, Linux and macOS
7983
/// Allows the Windows broker to list Work and School accounts as part of the <see cref="ClientApplicationBase.GetAccountsAsync()"/>
80-
/// Linux broker will discover accounts as part of the <see cref="ClientApplicationBase.GetAccountsAsync()"/>
84+
/// Linux and macOS broker will discover accounts as part of the <see cref="ClientApplicationBase.GetAccountsAsync()"/>
8185
/// </summary>
8286
public bool ListOperatingSystemAccounts { get; set; }
8387

@@ -90,6 +94,11 @@ internal bool IsBrokerEnabledOnCurrentOs()
9094
return true;
9195
}
9296

97+
if (EnabledOn.HasFlag(OperatingSystems.OSX) && DesktopOsHelper.IsMac())
98+
{
99+
return true;
100+
}
101+
93102
return false;
94103
}
95104
}

src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/DesktopOsHelper.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,15 @@ public static bool IsLinux()
4747

4848
public static bool IsMac()
4949
{
50-
#if MAC
51-
return true;
50+
#if __MOBILE__
51+
return false;
5252
#elif NETFRAMEWORK
5353
return Environment.OSVersion.Platform == PlatformID.MacOSX;
54-
#elif !__MOBILE__
55-
return RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
54+
#elif NET8_0_OR_GREATER
55+
string OSDescription = RuntimeInformation.OSDescription;
56+
return OSDescription.Contains("Darwin", StringComparison.OrdinalIgnoreCase);
5657
#else
57-
return false;
58+
return RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
5859
#endif
5960
}
6061

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Microsoft.Identity.Client.BrokerOptions.OperatingSystems.OSX = 4 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Microsoft.Identity.Client.BrokerOptions.OperatingSystems.OSX = 4 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Microsoft.Identity.Client.BrokerOptions.OperatingSystems.OSX = 4 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Microsoft.Identity.Client.BrokerOptions.OperatingSystems.OSX = 4 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Microsoft.Identity.Client.BrokerOptions.OperatingSystems.OSX = 4 -> Microsoft.Identity.Client.BrokerOptions.OperatingSystems

0 commit comments

Comments
 (0)