-
Notifications
You must be signed in to change notification settings - Fork 373
Description
Library version used
4.73.1.0
.NET version
Windows application targeting .NET Framework 4.6.2
Scenario
PublicClient - desktop app
Is this a new or an existing app?
The app is in production, and I have upgraded to a new version of MSAL
Issue description and reproduction steps
I am successfully creating an PublicClientApplicationBuilder
that opens the system default browser for authentication and redirects back to localhost as expected. However, if I call exactly the same code more than once, all subsequent attempts open the browser, but after authentication the localhost redirect fails with "localhost refused to connect".
Using netstat -ano | find "LISTEN"
I can see the random ephemeral port open and listening during authentication and this disappears after the redirect; the port number matches the browser URL, eg
TCP [::]:65457 [::]:0 LISTENING 4
http://localhost:65457/?code=xx&client_info=xx&state=xx
The only way to get the properly functioning again is to close the application and start a new instance, so I suspect the local socket is not being released and as there is no Dispose()
method for IPublicClientApplication
there seems no way to do this through code?
Therefore, this makes for a poor use experience as the browser makes it look like it's failed.
Two points of note:-
- In my application code where I create storage cache for the token file, even if I delete this and call
oAuthApp.RemoveAsync()
on all the accounts held, despite the apparent failure, subsequent Graph calls are actually successful. - If intercepting traffic with Fiddler, all attempts are always successful.
Relevant code snippets
#
private Microsoft.Identity.Client.IPublicClientApplication oAuthApp;
private async System.Threading.Tasks.Task<bool> foo() {
oAuthApp = Microsoft.Identity.Client.PublicClientApplicationBuilder.Create(clientId)
.WithAuthority("https://login.microsoftonline.com/common")
.WithRedirectUri("http://localhost")
.Build();
String[] scopes = new string[] { "user.read", "Calendars.ReadWrite", "Calendars.ReadWrite.Shared" };
Microsoft.Identity.Client.IAccount firstAccount = (await oAuthApp.GetAccountsAsync()).FirstOrDefault();
Microsoft.Identity.Client.AuthenticationResult authResult = await oAuthApp.AcquireTokenInteractive(scopes)
.WithAccount(firstAccount)
.WithPrompt(Microsoft.Identity.Client.Prompt.SelectAccount)
.WithUseEmbeddedWebView(false)
.ExecuteAsync();
return true;
}
public void test() {
var bar = System.Threading.Tasks.Task.Run(async () => { await foo(); });
bar = System.Threading.Tasks.Task.Run(async () => { await foo(); });
}
Expected behavior
Any subsequent attempts to authenticate following the initial one, should also successfully redirect to the localhost port and give a proper "this window can now be closed" message (not "connection refused").
Identity provider
Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)
Regression
No response
Solution and workarounds
- Close the application and reopen - not really a workaround
- Intercept local traffic with Fiddler - not a production solution.