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.
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
PublicClientApplicationBuilderthat 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, egTCP [::]:65457 [::]:0 LISTENING 4http://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 forIPublicClientApplicationthere 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:-
oAuthApp.RemoveAsync()on all the accounts held, despite the apparent failure, subsequent Graph calls are actually successful.Relevant code snippets
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