Skip to content

Commit f473844

Browse files
pwoosamPatrick Woo-Sam
andauthored
Fallback to interactive browser auth if broker is enabled (#598)
If broker auth is enabled but fails, then try interactive browser auth, before device code. --------- Co-authored-by: Patrick Woo-Sam <[email protected]>
1 parent e479cc5 commit f473844

File tree

2 files changed

+39
-11
lines changed

2 files changed

+39
-11
lines changed

CredentialProvider.Microsoft/CredentialProviders/Vsts/MsalTokenProvidersFactory.cs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Threading.Tasks;
88
using Microsoft.Artifacts.Authentication;
99
using Microsoft.Extensions.Logging;
10+
using Microsoft.Identity.Client;
1011
using Microsoft.Identity.Client.Extensions.Msal;
1112
using NuGetCredentialProvider.Util;
1213

@@ -29,7 +30,7 @@ public async Task<IEnumerable<ITokenProvider>> GetAsync(Uri authority)
2930
cache = await MsalCache.GetMsalCacheHelperAsync(EnvUtil.GetMsalCacheLocation(), logger);
3031
}
3132

32-
var builder = AzureArtifacts.CreateDefaultBuilder(authority)
33+
var app = AzureArtifacts.CreateDefaultBuilder(authority)
3334
.WithHttpClientFactory(HttpClientFactory.Default)
3435
.WithLogging(
3536
(Microsoft.Identity.Client.LogLevel level, string message, bool containsPii) =>
@@ -38,18 +39,36 @@ public async Task<IEnumerable<ITokenProvider>> GetAsync(Uri authority)
3839
logger.LogTrace("MSAL Log ({level}): {message}", level, message);
3940
},
4041
enablePiiLogging: EnvUtil.GetLogPIIEnabled()
41-
);
42-
43-
var app = builder
44-
.Build();
45-
var appInteractiveBroker = builder
46-
.WithBroker(EnvUtil.MsalAllowBrokerEnabled(), EnvUtil.GetMsalBrokerWindowHandle(), logger)
42+
)
4743
.Build();
4844

45+
var brokerEnabled = EnvUtil.MsalAllowBrokerEnabled();
46+
#nullable enable
47+
IPublicClientApplication? appInteractiveBroker = null;
48+
#nullable disable
49+
if (brokerEnabled)
50+
{
51+
appInteractiveBroker = AzureArtifacts.CreateDefaultBuilder(authority)
52+
.WithHttpClientFactory(HttpClientFactory.Default)
53+
.WithLogging(
54+
(Microsoft.Identity.Client.LogLevel level, string message, bool containsPii) =>
55+
{
56+
// We ignore containsPii param because we are passing in enablePiiLogging below.
57+
logger.LogTrace("MSAL Log ({level}): {message}", level, message);
58+
},
59+
enablePiiLogging: EnvUtil.GetLogPIIEnabled()
60+
)
61+
.WithBroker(brokerEnabled, EnvUtil.GetMsalBrokerWindowHandle(), logger)
62+
.Build();
63+
}
64+
4965
cache?.RegisterCache(app.UserTokenCache);
50-
cache?.RegisterCache(appInteractiveBroker.UserTokenCache);
66+
if (appInteractiveBroker != null)
67+
{
68+
cache?.RegisterCache(appInteractiveBroker.UserTokenCache);
69+
}
5170

52-
return MsalTokenProviders.Get(app, appInteractiveBroker, logger);
71+
return MsalTokenProviders.Get(app, logger, appInteractiveBroker: appInteractiveBroker);
5372
}
5473
}
5574
}

src/Authentication/MsalTokenProviders.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.Artifacts.Authentication;
99

1010
public class MsalTokenProviders
1111
{
12-
public static IEnumerable<ITokenProvider> Get(IPublicClientApplication app, IPublicClientApplication appInteractiveBroker, ILogger logger)
12+
public static IEnumerable<ITokenProvider> Get(IPublicClientApplication app, ILogger logger, IPublicClientApplication? appInteractiveBroker = null)
1313
{
1414
yield return new MsalServicePrincipalTokenProvider(app, logger);
1515
yield return new MsalManagedIdentityTokenProvider(app, logger);
@@ -22,7 +22,16 @@ public static IEnumerable<ITokenProvider> Get(IPublicClientApplication app, IPub
2222
yield return new MsalIntegratedWindowsAuthTokenProvider(app, logger);
2323
}
2424

25-
yield return new MsalInteractiveTokenProvider(appInteractiveBroker, logger);
25+
// Use broker authentication first if enabled
26+
if (appInteractiveBroker != null)
27+
{
28+
yield return new MsalInteractiveTokenProvider(appInteractiveBroker, logger);
29+
}
30+
31+
// Fallback to non-broker interactive browser auth
32+
yield return new MsalInteractiveTokenProvider(app, logger);
33+
34+
// Fallback to device code flow as last resort
2635
yield return new MsalDeviceCodeTokenProvider(app, logger);
2736
}
2837
}

0 commit comments

Comments
 (0)