Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] PlatformNotSupportedException in AcquireTokenInteractive call #1918

Closed
1 of 7 tasks
maxk1219 opened this issue Jul 8, 2020 · 14 comments
Closed
1 of 7 tasks

[Bug] PlatformNotSupportedException in AcquireTokenInteractive call #1918

maxk1219 opened this issue Jul 8, 2020 · 14 comments
Assignees

Comments

@maxk1219
Copy link

maxk1219 commented Jul 8, 2020

Which Version of MSAL are you using ?
Note that to get help, you need to run the latest version. Preview version are also ok.
For ADAL, please log issues to https://github.com/AzureAD/azure-activedirectory-library-for-dotnet

4.16.0
Platform

netstandard2.0
What authentication flow has the issue?

  • Desktop / Mobile
    • Interactive
    • Integrated Windows Auth
    • Username Password
    • Device code flow (browserless)
  • Web App
    • Authorization code
    • OBO
  • Web API
    • OBO

Other? - please describe;

Is this a new or existing app?

This is a new app or experiment
Repro

 authResult = await app.AcquireTokenInteractive(scopes)
                .ExecuteAsync().ConfigureAwait(false);

Expected behavior
A clear and concise description of what you expected to happen (or code).
Interactive UI pop-up should show up for sign-in.
Actual behavior
A clear and concise description of what happens, e.g. exception is thrown, UI freezes
Following exception is thrown:
System.PlatformNotSupportedException
HResult=0x80131539
Message=Possible Cause: If you are using an XForms app, or generally a netstandard assembly, make sure you add a reference to Microsoft.Identity.Client.dll from each platform assembly (e.g. UWP, Android, iOS), not just from the common netstandard assembly
Source=Microsoft.Identity.Client
StackTrace:
at Microsoft.Identity.Client.Platforms.netstandard13.WebUIFactory.CreateAuthenticationDialog(CoreUIParent parent, RequestContext requestContext)
at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.CreateWebAuthenticationDialog()
at Microsoft.Identity.Client.Internal.AuthCodeRequestComponent.d__4.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.d__11.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.d__8.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.d__14.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.d__2.MoveNext()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.DevCanvas.Common.Providers.AuthZMsalProvider.d__2.MoveNext() in D:\devcanvas\Analyzers\Analyzers\Extensions\AuthZMsalProvider.cs:line 41

This exception was originally thrown at this call stack:
[External Code]
Microsoft.DevCanvas.Common.Providers.AuthZMsalProvider.GetInteractiveFlowToken() in AuthZMsalProvider.cs

Possible Solution

Additional context/ Logs / Screenshots
Add any other context about the problem here, such as logs and screebshots. Logging is described at https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/logging

@bgavrilMS
Copy link
Member

bgavrilMS commented Jul 8, 2020

MSAL is indeed built against .NETSTDARD (v 1.3), but on this platform we were not able to implement interactive authentication due to some limitations in that target framework (missing APIs around HttpListener)

I can see a few ways to fix your problem:

  1. In the grand majority of cases, the entry point application is either .net classic or .net core, so if you add MSAL as a dependency on the entry point app, that version of MSAL.dll will be used.
  2. Since your target framework is .netstandard 2, where the aforementioned APIs exist, you could copy the logic for popping up the browser and inject into MSAL through the extensibility point ICustomWebUi . I can help with this.
  3. MSAL adds .net standard 2.0 to the list of frameworks and we implement it there. I'm a little hesitant to commit to this because we have SO many frameworks already that our builds are very slow.

@maxk1219
Copy link
Author

maxk1219 commented Jul 8, 2020

Thanks, Bogdan, for quick reply. Entry point app for my VS extension library is Visual Studio app so I don't have much flexibility for #1 there. Option #2 is an alternative, I was also considering using client credential flow in case if interactive does not work. It will require installing of a certificate on client machine but probably still less work then building UI extension via ICustomWebUI. I'll try this first and let you know if I spot any issues.

@bgavrilMS
Copy link
Member

@henrik-me @jmprieur - this scenario is interesting because it showcases a use for pure .netstandard implementation.

@bgavrilMS
Copy link
Member

@maxk1219 - isn't there a way to get a token using Visual Studio's internal identity service or some other VS extensibility mechanism? VS 2019 already references MSAL so it is in memory already...

@maxk1219
Copy link
Author

maxk1219 commented Jul 8, 2020

@maxk1219 - isn't there a way to get a token using Visual Studio's internal identity service or some other VS extensibility mechanism? VS 2019 already references MSAL so it is in memory already...

It is another option although I'm not sure if I can force VS to sign in if user decides not to do so. Also from library point of view I'm trying to package it in a way so it is not dependent on VS or its state since it can be also installed as a nuget package, not an extension.

One more interesting observation. I was able to get a token from MSAL using my library if it is loaded as an extension in VS and everything is under single project including MSAL references. When I use it as a nuget or split code in multiple projects, it throws PlatformNotSupportedException. I don't understand why multiple projects would make such difference, but nuget package could use different context from VS extension which has access to UI I presume.

@jmprieur
Copy link
Contributor

jmprieur commented Jul 9, 2020

Yes, that make sense @bgavrilMS

@bgavrilMS
Copy link
Member

bgavrilMS commented Jul 9, 2020

@maxk1219 - this is because at runtime you can only have 1 MSAL assembly in memory. And when NuGet intervenes in the build pipeline, it sees that in the dependency graph there is MSAL for .net classic (brought in by VS) and MSAL for netstandard (brought in by you) and it chooses the .net classic version.

@henrik-me @jmprieur - how do you feel about introducing a .netstandard 2.0 or 2.1 target for MSAL, along with our .netstandard 1.3 version, but which could include system browser support. Alternatively, we could add an implementation based on TCP Listener in .netstandard (we used to have it already, but there were some bugs with it). Or rely on ICustomWebUi

@bgavrilMS bgavrilMS self-assigned this Jul 9, 2020
@henrik-me
Copy link
Contributor

netstandard 2.0 has some interesting challenges on net framework, as you actually need .net 4.7.2 for it to really work (long story of troubles). However netstandard 2.0 is the last netstandard 2.0 version which has a meaning for net framework, thus I blieve we should be targeting netstandard 2.0 and consider having it behave like our netcore target?

Please see additional information under the table here:
https://github.com/dotnet/standard/blob/master/docs/versions.md

Copy pasted the interesting parts from the above here:
1 The versions listed here represent the rules that NuGet uses to determine whether a given .NET Standard library is applicable. While NuGet considers .NET Framework 4.6.1 as supporting .NET Standard 1.5 through 2.0, there are several issues with consuming .NET Standard libraries that were built for those versions from .NET Framework 4.6.1 projects. For .NET Framework projects that need to use such libraries, we recommend that you upgrade the project to target .NET Framework 4.7.2 or higher.

2 .NET Framework will not support .NET Standard 2.1 or any other later version. For more details, see this blog post.

@bgavrilMS
Copy link
Member

Closing as a duplicate of #1991

@jmprieur
Copy link
Contributor

jmprieur commented Nov 6, 2021

@bgavrilMS : reopening per @ShaneOss 's comment

@ShaneOss
Copy link

ShaneOss commented Nov 6, 2021

I get Exception thrown: 'System.PlatformNotSupportedException' in Microsoft.Identity.Client.dll
in UWP When using the following option on Application Builder.
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)

@bgavrilMS
Copy link
Member

Hi @ShaneOss - for mobile plantforms and UWP, MSAL takes care of the token cache for you:

  • on UWP it stores in it encrypted at rest (with DPAPI) in a file
  • on iOS it stores it in KeyChain
  • on Android in SharedPreferences

On other runtimes, we ask developers to define where the cache is stored etc.

https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=mobile

@svengrav
Copy link

@bgavrilMS Is there a sample for implementing the ICustomWebUi Interface? Im trying use the lib inside powershell 5.1 module and im getting the same error.
Possible cause: If you are using an XForms app, or generally a .NET Standard assembly, make sure you add a reference to Microsoft.Identity.Client.dll from each platform assembly (e.g. UWP, Android, iOS), not just from the common .NET Standard assembly. A browser is not available in the box on .NET Standard 1.3.)

Many thanks already :)

@bgavrilMS
Copy link
Member

I do not recommed it, it will not be easy to implement. Let's continue the discussion on Discussions tab.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants