Skip to content

Commit 21258ff

Browse files
Merge pull request #449 from AzureAD/user/chrmiller/respect-browser-env-var
Respect the $BROWSER environment variable when attempting to launch URLs
2 parents 30e5714 + 0fa7473 commit 21258ff

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

src/MSALWrapper/PCAWrapper.cs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ namespace Microsoft.Authentication.MSALWrapper
55
{
66
using System;
77
using System.Collections.Generic;
8+
using System.Diagnostics;
89
using System.Linq;
10+
using System.Runtime.InteropServices;
911
using System.Threading;
1012
using System.Threading.Tasks;
1113

@@ -83,14 +85,24 @@ public async Task<TokenResult> GetTokenSilentAsync(IEnumerable<string> scopes, I
8385
/// <inheritdoc/>
8486
public async Task<TokenResult> GetTokenInteractiveAsync(IEnumerable<string> scopes, IAccount account, CancellationToken cancellationToken)
8587
{
86-
AuthenticationResult result = await this.pca
88+
var builder = this.pca
8789
.AcquireTokenInteractive(scopes)
8890
.WithEmbeddedWebViewOptions(new EmbeddedWebViewOptions()
8991
{
9092
Title = this.PromptHint,
9193
})
9294
.WithUseEmbeddedWebView(this.UseEmbeddedWebView)
93-
.WithAccount(account)
95+
.WithAccount(account);
96+
97+
if (!this.UseEmbeddedWebView && RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
98+
{
99+
builder = builder.WithSystemWebViewOptions(new SystemWebViewOptions
100+
{
101+
OpenBrowserAsync = OpenBrowserOnLinuxAsync,
102+
});
103+
}
104+
105+
AuthenticationResult result = await builder
94106
.ExecuteAsync(cancellationToken)
95107
.ConfigureAwait(false);
96108
return this.TokenResultOrNull(result);
@@ -99,14 +111,24 @@ public async Task<TokenResult> GetTokenInteractiveAsync(IEnumerable<string> scop
99111
/// <inheritdoc/>
100112
public async Task<TokenResult> GetTokenInteractiveAsync(IEnumerable<string> scopes, string claims, CancellationToken cancellationToken)
101113
{
102-
AuthenticationResult result = await this.pca
114+
var builder = this.pca
103115
.AcquireTokenInteractive(scopes)
104116
.WithEmbeddedWebViewOptions(new EmbeddedWebViewOptions()
105117
{
106118
Title = this.PromptHint,
107119
})
108120
.WithUseEmbeddedWebView(this.UseEmbeddedWebView)
109-
.WithClaims(claims)
121+
.WithClaims(claims);
122+
123+
if (!this.UseEmbeddedWebView && RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
124+
{
125+
builder = builder.WithSystemWebViewOptions(new SystemWebViewOptions
126+
{
127+
OpenBrowserAsync = OpenBrowserOnLinuxAsync,
128+
});
129+
}
130+
131+
AuthenticationResult result = await builder
110132
.ExecuteAsync(cancellationToken)
111133
.ConfigureAwait(false);
112134
return this.TokenResultOrNull(result);
@@ -164,6 +186,26 @@ public async Task RemoveAsync(IAccount account)
164186
await this.pca.RemoveAsync(account);
165187
}
166188

189+
private static Task OpenBrowserOnLinuxAsync(Uri uri)
190+
{
191+
string browser = Environment.GetEnvironmentVariable("BROWSER");
192+
if (!string.IsNullOrEmpty(browser))
193+
{
194+
Process.Start(new ProcessStartInfo(browser, uri.AbsoluteUri)
195+
{
196+
UseShellExecute = false,
197+
});
198+
return Task.CompletedTask;
199+
}
200+
201+
// $BROWSER not set — fall back to default .NET behavior (UseShellExecute tries xdg-open etc.)
202+
Process.Start(new ProcessStartInfo(uri.AbsoluteUri)
203+
{
204+
UseShellExecute = true,
205+
});
206+
return Task.CompletedTask;
207+
}
208+
167209
private TokenResult TokenResultOrNull(AuthenticationResult result)
168210
{
169211
if (result == null || string.IsNullOrEmpty(result.AccessToken))

0 commit comments

Comments
 (0)