AzureAD / microsoft-identity-web

Helps creating protected web apps and web APIs with Microsoft identity platform and Azure AD B2C
MIT License
671 stars 208 forks source link

[Bug] Not compatible with .NET 6 and Azure Functions when calling AddMicrosoftIdentityWebApi #1548

Closed Mitars closed 4 months ago

Mitars commented 2 years ago

Which version of Microsoft Identity Web are you using? Microsoft Identity Web 1.21.0

Where is the issue?

Is this a new or an existing app? c. This is a new app or an experiment.

Repro

  1. In Visual Studio 2022 create a new project.

  2. Select Azure Functions template.

  3. Enter FunctionApp1 as the name and click Create.

  4. In the Create a new Azure Functions application prompt select a .NET 6 Empty template with a Storage account (AzureWebJobsStorage) see to None.

  5. Update the FunctionApp1.csproj with the following code:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
            <TargetFramework>net6.0</TargetFramework>
            <AzureFunctionsVersion>v4</AzureFunctionsVersion>
            <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
      </PropertyGroup>
      <ItemGroup>
            <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
            <PackageReference Include="Microsoft.Identity.Web" Version="1.21.0" />
            <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.0.1" />
      </ItemGroup>
      <ItemGroup>
            <None Update="host.json">
                  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            </None>
            <None Update="local.settings.json">
                  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
                  <CopyToPublishDirectory>Never</CopyToPublishDirectory>
            </None>
      </ItemGroup>
    </Project>

    Note: The line <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput> is required in order to bypass the issue noted here: https://github.com/AzureAD/microsoft-identity-web/issues/1428

  6. Create a class called Startup.cs and add the following code

    
    using FunctionApp1;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.Functions.Extensions.DependencyInjection;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Identity.Web;

[assembly: FunctionsStartup(typeof(Startup))]

namespace FunctionApp1;

public class Startup : FunctionsStartup { public override void Configure(IFunctionsHostBuilder builder) => builder.Services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.GetContext().Configuration.GetSection("Azure"));

[FunctionName("Function1")]
public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest request) =>
    request.HttpContext.AuthenticateAzureFunctionAsync().Result.Item2;

}


7. Build and then run the application.
8. Navigate to the URL **http://localhost:7071/api/Function1**.
9. You should get the following error when invoking the endpoint:

System.AggregateException: 'One or more errors occurred. (Method not found: 'Microsoft.IdentityModel.Tokens.TokenValidationParameters Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions.get_TokenValidationParameters()'.)'

Inner Exception MissingMethodException: Method not found: 'Microsoft.IdentityModel.Tokens.TokenValidationParameters Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions.get_TokenValidationParameters()'.



**Actual behavior**
The request.HttpContext.AuthenticateAzureFunctionsAsync() throws a Method not found exception.

**Expected behavior**
The request.HttpContext.AuthenticateAzureFunctionsAsync() should not throw a Method not found exception.

**Workaround**
Downgrading to version Microsoft Identity Web 1.12.0 or prior fixes this issue.

![snap issue](https://user-images.githubusercontent.com/33511441/143475452-fbe18f69-b97f-4ff8-8114-ee36445a2336.png)

![snap issue 2](https://user-images.githubusercontent.com/33511441/143475458-2470adf5-ea49-4204-8341-f278543e8306.png)
Fresher900 commented 2 years ago

I am also having the same issue. But before getting the error mentioned in the above comment, I am also getting a popup to download a class.

The function project was created using command "dotnet new func2 --auth SingleOrg --calls-graph"

image

dirthsj commented 2 years ago

This bug is blocking our upgrade to Azure Functions v4 / Dotnet 6, is there any ETA for resolution?

jmprieur commented 2 years ago

This is next on our priority list, @dirthsj But we are also working on some important internal commitments.

@jennyf19 and I would like to have a plan on what to do for Azure functions next week.

How do you create your azure functions with .NET 6?

dirthsj commented 2 years ago

It is good to hear this is on the priority list!

We are upgrading a dotnet 3.1 Azure Functions to .NET 6, following this guide, using In-Process functions.

Within our app, Microsoft.Identity.Web is used to identify AAD users and restrict access to certain data based on AAD Groups, and for calling internal company Apis using On-Behalf-Of flow.

luismanez commented 2 years ago

Any update here @jmprieur @jennyf19 ??

Hitting very similar issue, likely same cause. In my case, I´m not calling AddAuthentication as that break HttTriggers secured by Function code. My startup has:

var authBuilder = new AuthenticationBuilder(services);
            authBuilder.AddMicrosoftIdentityWebApi(configuration.GetSection("AzureAd"))
                .EnableTokenAcquisitionToCallDownstreamApi()
                .AddMicrosoftGraphAppOnly(authProvider => new GraphServiceClient(authProvider))
                .AddInMemoryTokenCaches();

But when using the injected GraphServiceClient, I´m getting this issue:

Method not found: 'Microsoft.IdentityModel.Tokens.TokenValidationParameters Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions.get_TokenValidationParameters()'.

Stack trace:

   at Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderExtensions.<>c__DisplayClass3_0.<AddMicrosoftIdentityWebApiImplementation>b__0(JwtBearerOptions options, IServiceProvider serviceProvider, IOptionsMonitor`1 mergedOptionsMonitor, IOptionsMonitor`1 msIdOptionsMonitor, IOptions`1 msIdOptions)
   at Microsoft.Extensions.Options.ConfigureNamedOptions`5.Configure(String name, TOptions options)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at Microsoft.Azure.WebJobs.Hosting.WebJobsOptionsFactory`1.Create(String name) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\OptionsFormatter\WebJobsOptionsFactory.cs:line 57
   at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForAppAsync(String scope, String authenticationScheme, String tenant, TokenAcquisitionOptions tokenAcquisitionOptions)
   at Microsoft.Identity.Web.TokenAcquisitionAuthenticationProvider.<AuthenticateRequestAsync>d__3.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Graph.AuthenticationHandler.<SendAsync>d__16.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.Http.HttpClient.<<SendAsync>g__Core|83_0>d.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   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.Graph.HttpProvider.<SendRequestAsync>d__19.MoveNext()

This also blocking us to move our product to .NET 6 and latest ms-identity-web :(

Thanks.

jmprieur commented 2 years ago

@Mitars, @newbiedev123, @dirthsj, @luismanez:

The Azure function team is fixing the issue on their side (The PR is https://github.com/Azure/azure-functions-host/pull/8129). Please use that PR to get the update. When this is fixed, this should just work.

Note that we also have a number of improvements around the support of Azure functions by Id.Web, which are blocked by this issue: See https://github.com/AzureAD/microsoft-identity-web/projects/44 for that backlog. We'll resume that work when the Azure function work is fixed and deployed.

luismanez commented 2 years ago

Thanks a ton @jmprieur !! that helps a lot. Just curious regarding:

use that PR to get the update.

As this is the functions host, it would work just locally, right? I don´t even know how to make it work locally, as this is included in the Functions tooling... anyway, just curious if you were thinking a different thing. I´m gonna wait till the fix is published, and then retake my code upgrade.

Thanks again!

luismanez commented 2 years ago

BTW, this Twitter thread has good info, and a possible workaround if you don´t mind to go with ms-identity-web 1.5.1 https://twitter.com/luismanez/status/1491533220709605387

dirthsj commented 2 years ago

@jmprieur it looks like that PR was merged and released with in 4.2.0, can you confirm this version does include the fix?

jmprieur commented 2 years ago

@jennyf19 : it seems the Azure function work could be unblocked.

jennyf19 commented 2 years ago

That's great! Thanks for checking on this @dirthsj! I will try to carve out time in the next day or two to come back to this.

dirthsj commented 2 years ago

@jennyf19 have you taken a look at this yet? My team is trying to decide if we can update in our next sprint.

luismanez commented 2 years ago

@jennyf19 I´d be happy to help to test it, but not sure how to do it. I have a small project that reproduces the issue, but works with Visual Studio, and I don´t think I can update Az Func tools in Visual Studio. Can I help somehow? we also want to move to .net 6 as soon as possible. thanks!

jennyf19 commented 2 years ago

@luismanez I've asked the Az Functions team how to pick up the changes, I'm waiting to hear back from them.

cichyr commented 2 years ago

Hi, is there any update on this bug? Is it in testing phase or maybe there is already fixed version release ETA?

luismanez commented 2 years ago

@jennyf19 BTW, I updated yesterday my VS 2022, but the Functions tools are not updated yet, so still same issue... (haven´t tried the VS Preview version)

dirthsj commented 2 years ago

@luismanez I've been looking into this and the PR for functions tools update is here https://github.com/Azure/azure-functions-core-tools/pull/2972

luismanez commented 2 years ago

Hi @dirthsj , yeah, but if you download that version, Visual Studio is still using its "internal" version. The way to test it might be to download that version, and create an Az Function using func CLI and VS Code, but I´m not experienced with it and have no time to test it. Hope MS updates VS with latest Az Func tools the sooner...

luismanez commented 2 years ago

Hi @jennyf19. Any update here? Could you ask to Az Functions team again? I got this response a month ago: https://twitter.com/anirudhgarg/status/1505364701844164609

I´ve re-tested it with my VS2021 preview (17.2.0 Preview 4.0), but still same error.

I know is not on your side, and appreciate your help, but it´s a bit annoying that 3.1 support will end in 7 months, and we cannot upgrade yet to .NET 6 and latest MS Identity.Web :(

Thanks.

jennyf19 commented 2 years ago

@luismanez I tried with this: Azure Functions Core Tools Core Tools Version: 4.0.4483 Commit hash: N/A (64-bit) Function Runtime Version: 4.1.3.17473

In both VS 17.1.5 and 17.2.0 Preview 4, I am still hitting the same issue. I've asked the Azure Functions team for an update, as last we heard, it was supposed to be available beginning of April. Will keep you posted.

luismanez commented 2 years ago

Thank you very much for testing and confirming my results. Hope you get an update from the Az Functions team (no luck for me on twitter). Thanks again.

jennyf19 commented 2 years ago

@luismanez I just tried w/the last VS updates (and w/preview update), but same result :( Still waiting for news as well.

luismanez commented 2 years ago

@jennyf19 yeah, just tested and same experience (VS2022 17.2.0 Preview 5.0). Seems the Core tools version hasn´t changed...

image

Thanks a lot for checking and chasing this. Really appreciate it.

luismanez commented 2 years ago

New VS2022 17.2.0 preview 6.0... Old issues... still same Az Tools.... this is really frustrating and totally disappointed on the Az Functions team :(

muzzar78 commented 2 years ago

Any ETA on when the fix will be available? This is blocking us as well :-(

jmprieur commented 2 years ago

This is blocking everybody, @muzzar78 (us included)

abidCharlotte49er commented 2 years ago

We are working on .NET Core 6.0 APIs that are hosted on AWS Lambdas we are getting the same error while working with JWTs. Is this AWS issue or issue in .NET Core API ? It works fine locally but not on Lambda.

jennyf19 commented 2 years ago

@luismanez I just tried with latest VS 2022 preview update, but Azure Core Tools was not updated :(

luismanez commented 2 years ago

Thanks for testing it again @jennyf19 . Same experience here (so frustrating...)

jennyf19 commented 2 years ago

@luismanez can you send me an email at jeferrie@microsoft.com?

Rough ETA is another 2 weeks.

dirthsj commented 2 years ago

Function Runtime Version is showing as 4.3.2 on stable visual studio 2022 today!

We've migrated to a different solution so I am unable to test if this resolved the issue.

thduttonuk commented 2 years ago

Still happening on Function Runtime 4.3.2.18186 for me.

dawpol commented 2 years ago

image

Still the same issue, any update?

Yomodo commented 2 years ago

image

STILL....

luismanez commented 2 years ago

I literally gave up. I´m not using the library in Az Functions v4 with .net 6 (not working and can´t wait to upgrade my project, as MS is deprecating .net 3.1 in less than 6 months). For my Az Functions, I´m using MSAL directly with ClientCredentials flow. It´s a shame, but I have no option. Last, I must say that this is not on this MS team. Jenny and Jean-Marc have been helping as much as they can, but is on Az Functions team.

thduttonuk commented 2 years ago

Update to the latest and still get the issue

System.MissingMethodException: 'Method not found: 'Microsoft.IdentityModel.Tokens.TokenValidationParameters Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions.get_TokenValidationParameters()'.'

image

rossdargan commented 1 year ago

This is still an issue.

image

jennyf19 commented 1 year ago

The Azure Functions team is re-visiting this. Will post any updates here.

luismanez commented 1 year ago

Thanks @jennyf19 BTW, 2 days ago I tested latest MS Identity web in an Az Functions project with an HttpTrigger. With the new Factory, I was able to inject the TokenAcquisition etc, but when running, I got the same issue with not finding some version of the IdentityModel class (if memory serves me well). I was NOT using Az Function isolated mode, so, I guess the Functions runtime, is using a different version of some of the libraries using by MS Identity web...

nlz242 commented 1 year ago

Thanks @jennyf19 BTW, 2 days ago I tested latest MS Identity web in an Az Functions project with an HttpTrigger. With the new Factory, I was able to inject the TokenAcquisition etc, but when running, I got the same issue with not finding some version of the IdentityModel class (if memory serves me well). I was NOT using Az Function isolated mode, so, I guess the Functions runtime, is using a different version of some of the libraries using by MS Identity web...

Yeah, I'm getting Method not found on both Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions.set_TokenValidationParameters(Microsoft.IdentityModel.Tokens.TokenValidationParameters) and Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions.get_TokenValidationParameters()

Seeing as this is gonna be an issue forever, because of how the Azure Function team delivers their runtime, can we get a table with Azure Function Runtime versions and their compatible Microsoft.Identity.Web versions? At this point, i have abandoned the tought of having a common lib for my WebApps and Function Apps. Having it documented would at least allow people to pick the proper version for the current runtime, without having to go thru 3 or 4 issues on github and trying to mix'n'match.

theofred commented 1 year ago

@jennyf19 Any updates on this?

jc4gh commented 1 year ago

I've got around the issue for now by adding these.

 .ConfigureLogging(logging => logging
      .AddFilter<ApplicationInsightsLoggerProvider>(null, LogLevel.Information)
      .AddFilter<ApplicationInsightsLoggerProvider>("Azure.Core", LogLevel.Warning)
      .AddFilter<ApplicationInsightsLoggerProvider>("Azure.Identity", LogLevel.Warning)
      .AddFilter<ApplicationInsightsLoggerProvider>("Microsoft.Identity.Web.TokenAcquisition", LogLevel.Warning))
luismanez commented 1 year ago

haven't had the chance to test the workaround. Anyone else can confirm it works? cos seems very weird to me, as the issue is related about not finding some methods in the "Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerOptions" class, so I don't understand how configuring some logging filters is fixing the issue. Thanks.

husseinkorly commented 1 year ago

good question. can someone explain how configuring logging filter fixes the issue? I tried it on our project and it didn't work!

@jmprieur and @jennyf19 we need update the package to the latest version to get the update for System.Security.Cryptography.Pkcs that has vulnerability issues. I also see you added a label for work-around-available. did you try the work around and does it work for you?

c0rn3liusha11 commented 11 months ago

Are there any updates on this issue that seems to have been blocking for almost 2 years now? Has anyone encountered this issue when using Microsoft.Identity.Client (as opposed to Microsoft.Identity.Web)? As a data point, my issue has a slightly different 'signature', but the logging configuration work-around noted above DID NOT work around the issue for me.

Details: Azure Functions Runtime ~4 Code built targeting dotnet6 using dotnet7 SDK/Tools From within code attempting to use a (internal) library that uses Azure.Identity to eventually do Jwt Token Validation. Have tried Azure.Identity v1.8.2 (the version our internal library directly depends on), v1.9.0 and v1.10.0. Without dumping the whole stack here, the tl;dr; is that a call to Azure.Identity.ClientSecretCredential GetTokenAsync fails with message The type initializer for 'Microsoft.Identity.Client.Platforms.net6.MsalJsonSerializerContext' threw an exception. Digging deeper, this happens in Azure.Identity.MsalConfidentialClient when it is calling AcquireTokenForClientAsync and appears to be a System.MissingMethodException coming from MsalJsonSerializerContext..ctor with the message Method not found: 'System.Text.Json.JsonEncodedText System.Text.Json.JsonEncodedText.Encode(System.String, System.Text.Encodings.Web.JavaScriptEncoder)'.

husseinkorly commented 10 months ago

Here's a work around for updating the package:

I will update this thread once the issue being fixed completely without any workaround.

briandunnington commented 4 months ago

I know this is a really old thread, but with the release of Azure Functions isolated mode, this is now possible. Since isolated mode essentially works like a console app and runs in a separate process from the Functions runtime, there are not package conflicts with the internal Microsoft.IdentityModel packages and others.

Because of this, we were able to successfully integrate with our .NET 8 isolated mode functions. (I know the title of this references .NET 6 but it was also opened in 2021 and a lot has changed in .NET/Azure Functions since then)