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

Microsoft.AspNetCore.DataProtection - IOC error #5447

Closed
petrce opened this issue Jan 8, 2020 · 34 comments
Closed

Microsoft.AspNetCore.DataProtection - IOC error #5447

petrce opened this issue Jan 8, 2020 · 34 comments

Comments

@petrce
Copy link

petrce commented Jan 8, 2020

After updating my function to v3 I get this error on startup:

[08/01/2020 15:11:34] Loading startup extension 'Startup'
[08/01/2020 15:11:34] Loaded extension 'Startup' (1.0.0.0)
[08/01/2020 15:11:34] A host error has occurred during startup operation 'fba5bef3-a5ce-4006-a20a-160977aca2d8'.
[08/01/2020 15:11:34] func: Invalid host services. Microsoft.Azure.WebJobs.Script.WebHost: The following service registrations did not match the expected services:
[08/01/2020 15:11:34]   [Invalid] ServiceType: Microsoft.Extensions.Hosting.IHostedService, Lifetime: Singleton, ImplementationType: Microsoft.AspNetCore.DataProtection.Internal.DataProtectionHostedService.
Value cannot be null. (Parameter 'provider')

This is my current setup:

  • Microsoft Visual Studio Professional 2019 Version 16.4.2
  • azure-functions-core-tools@3.0.2009

And this is my .csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.DataProtection.AzureKeyVault" Version="3.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.DataProtection.AzureStorage" Version="3.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.DataProtection.Abstractions" Version="3.1.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

Startup.cs file:

using System;
using FunctionApp1;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.Storage.Auth;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Extensions.DependencyInjection;


[assembly: FunctionsStartup(typeof(Startup))]

namespace FunctionApp1
{
    internal class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var storageUri = new Uri("https://potato");

            var blobClient = new CloudBlobClient(storageUri, new StorageCredentials("accountname", "pass"));
            var container = blobClient.GetContainerReference("test");

            builder.Services.AddDataProtection()
                .PersistKeysToAzureBlobStorage(container, "test")
                .ProtectKeysWithAzureKeyVault("test", "test", "test");
        }
    }
}

It was definitely working in 2.2
Downgrading Microsoft.AspNetCore.DataProtection packages do not help.
Running from VS or in the command line returns the same error.

The only solution is to do not upgrade to the v3 function app :(

@ankitkumarr ankitkumarr transferred this issue from Azure/azure-functions-core-tools Jan 8, 2020
@ankitkumarr
Copy link
Contributor

Moved this to the host repository.

I was able to repro this. builder.Services.AddDataProtection(); throws the exception in the issue.
@brettsam or @fabiocav, would you have any input on this, if you have seen this before or are aware what might be causing this?

@brettsam
Copy link
Member

brettsam commented Jan 8, 2020

We don't allow you to register any IHostedService as a part of your Startup operation. It looks like with this commit in ASP.NET -- dotnet/aspnetcore@f35564b#diff-4d562a5c817ba193b1543e1f132dff24 -- this service changed from an IStartupFilter to an IHostedService.

Without doing some research I don't know whether we should open this class up or not to allow it to be used -- @fabiocav any ideas here?

@fabiocav
Copy link
Member

fabiocav commented Jan 8, 2020

We can discuss the options (which could also mean adding that as an optional service), but it will indeed require a bit of investigation to understand the impact.

@petrce
Copy link
Author

petrce commented Jan 8, 2020

can I help somehow?

@petrce
Copy link
Author

petrce commented Jan 8, 2020

Also, please do you have any idea about how to use a 2.2 version of Microsoft.AspNetCore.DataProtection in v3 function for now? Because the function runner is trying to use 3.1 of Microsoft.AspNetCore.DataProtection version from func.exe folder, regardless of what nuget package of DataProtection I use.

@fabiocav
Copy link
Member

fabiocav commented Jan 8, 2020

@petrce 3.0 unifies on framework dependencies for .NET Core 3.1, that's not something you'd have the ability to override.

Allowing this dependency to register a hosted service shouldn't be an issue, we'll keep you updated here.

@danielearwicker
Copy link

This seems like an example of the same kind of problem but with healthchecks, which also wants to register an IHostedService of its own.

@Tratcher
Copy link

We don't allow you to register any IHostedService as a part of your Startup operation.

Why not?

@fabiocav
Copy link
Member

@Tratcher allowing custom logic (potentially background services) to run outside of the context of a function is not something we can promote as supported today because of a few issues. The top ones being:

  • This would not play well with the dynamic scaling infrastructure. The scale controller is not aware of any logic running outside of the context of a function execution, and may scale in if it believes an application is idle. Customers would not have a reliable mechanism to keep that running unless they're artificially triggering function executions, and this would certainly generate confusion and support cases.
  • The runtime and Functions infrastructure is not setup for compute use outside of the context of a function. Allowing the registration of custom hosted services would expose a feature that enables that, which would not play well with other infrastructure components (including fraud detection which could severely impact a customer's application)

Those are solvable problems, but problems that exist today. Until we can invest on the changes required to properly support registration of custom hosted services and ensure a good experience, we intend to keep this restriction in place.

@petrce
Copy link
Author

petrce commented Jan 17, 2020

Wow, so that means that in foreseeable future there is no way to make Microsoft.AspNetCore.DataProtection working in Azure Function v3?

that is really a bummer for me :( so I will have to migrate my APIs to different data protection if I want to use the .NET Core 3

@zebslc
Copy link

zebslc commented Jan 22, 2020

Surely this should be listed in https://docs.microsoft.com/en-us/dotnet/core/compatibility/2.2-3.1 ? - the only mentionto data protection is about a change in storage namespace but this breaks our application totally. :-(

@Tratcher
Copy link

@zebslc this is a Functions specific limitation.

@zebslc
Copy link

zebslc commented Jan 22, 2020

In which case it could have been in there with brackets (affects function apps only). This is still a breaking change for users of this version migrating from v2 & would have been useful to know about so we could have made time to re-write/remove it.

@LukeKolodziej
Copy link

Also ran into this issue when trying to migrate to v3. I am registering RazorPages/RazorViewEngine which registers the DataProtection library.

@rainerllera
Copy link

same here @LukeKolodziej . Any updates on this?

@Leon99
Copy link

Leon99 commented Jan 31, 2020

Also, looks like .AddAuthentication() is not supported anymore as well - it calls .AddDataProtection() internally.
So what's the plan to tackle this, @fabiocav? Will there be a fix in the short-term either from AF or from DataProtection side?

@espray
Copy link

espray commented Jan 31, 2020

.AddAuthentication() never worked

@davidfowl
Copy link
Member

@fabiocav Can you special case that concrete type? https://github.com/dotnet/aspnetcore/blob/6255c1ed960f5277d2e96ac2d0968c2c7e844ce2/src/DataProtection/DataProtection/src/Internal/DataProtectionHostedService.cs#L35

This will at least unblock people for now while we figure out what a longer term solution looks like.

@Leon99
Copy link

Leon99 commented Feb 2, 2020

@espray I can say for sure that it didn't throw an exception on startup

@espray
Copy link

espray commented Feb 3, 2020

@Leon99 correct it wont exception at startup, it will fail when trying to service the http request

@ranjithsnair
Copy link

Any update on this issue? I just need to implement AAD role based authentication in Azure function v3 but when calling AddAuthentication never works failed with HostService error. If there is any other solutions for AAD role based authentication in AzFunctions v3 let me know

@hiranamarasinghe
Copy link

I was able fix this issue while using IWebJobsStartup instead of FunctionsStartup. The issue seems to be IFunctionsHostBuilder in the DI container.

So this might work with this line of code in Startup.cs

public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder) =>
builder.AddDependencyInjection(ConfigureServices);

private void ConfigureServices(IServiceCollection services)
{
  // Your code
}

}
So basically the issue is in the IFunctionsHostBuilder.

In order to resolve dependencies you need to use third party DI container and I used Willezone.Azure.WebJobs.Extension.

@MattJeanes
Copy link

For those implicitly using the DataProtectionHostedService i.e. by using AddIdentity or similar you can remove it by using this line after

builder.Services.Remove(builder.Services.First(x => x.ImplementationType?.Name == "DataProtectionHostedService"));

This works around the issue for my use case, but this definitely needs a proper solution as this is an undocumented breaking change between V2 and V3, nothing about it on the migration guide.

@fabiocav
Copy link
Member

Just an update on this. We'll be removing this restriction for data protection. @brettsam can share more information if needed, but this restriction will be lifted in the release for the current sprint (set to begin at the end of next week)

@dancundy
Copy link

@fabiocav When does the sprint end? I.E, when would this fix be release? Just wondering if I should hold out and wait and work on other things in the mean time.

@andresrsanchez
Copy link

For those implicitly using the DataProtectionHostedService i.e. by using AddIdentity or similar you can remove it by using this line after

builder.Services.Remove(builder.Services.First(x => x.ImplementationType?.Name == "DataProtectionHostedService"));

This works around the issue for my use case, but this definitely needs a proper solution as this is an undocumented breaking change between V2 and V3, nothing about it on the migration guide.

With this i got it working on my computer (emulator), but not in Azure :(
The message is "The function runtime is unable to start", and that's it. Anyone knows?
Thanks!!

@MattJeanes
Copy link

@andresrsanchez same, but the function seems to be running anyway - see if that's the case for you too!

@andresrsanchez
Copy link

@andresrsanchez same, but the function seems to be running anyway - see if that's the case for you too!

image
This is my case, no functions in here!!
I'm going to revert a few things :(

@andresrsanchez
Copy link

@MattJeanes ok i see now, it isnt executing in my case :(

@dancundy
Copy link

For those implicitly using the DataProtectionHostedService i.e. by using AddIdentity or similar you can remove it by using this line after

builder.Services.Remove(builder.Services.First(x => x.ImplementationType?.Name == "DataProtectionHostedService"));

This works around the issue for my use case, but this definitely needs a proper solution as this is an undocumented breaking change between V2 and V3, nothing about it on the migration guide.

With this i got it working on my computer (emulator), but not in Azure :(
The message is "The function runtime is unable to start", and that's it. Anyone knows?
Thanks!!

Can you post the full error? I have something similar, see below.

image

@andresrsanchez
Copy link

@dancundy sadly that's the full error :(
u can try downgrading microsoft.extensions packages from 3.1 to 3.0 versions like this: Azure/azure-functions-dotnet-extensions#32 (comment)

@petrce
Copy link
Author

petrce commented May 6, 2020

Just an update on this. We'll be removing this restriction for data protection. @brettsam can share more information if needed, but this restriction will be lifted in the release for the current sprint (set to begin at the end of next week)

Hi so it works now and this issue can be closed?

@brettsam
Copy link
Member

brettsam commented May 6, 2020

Yes it looks like this is now deployed to production -- I don't believe that the core tools (or VS tools) have been updated yet but that will be coming soon.

@brettsam brettsam closed this as completed May 6, 2020
@mcgear
Copy link

mcgear commented May 9, 2020

Are there any prerelease builds of core tools that could be used yet for this?

@ghost ghost locked as resolved and limited conversation to collaborators Jun 8, 2020
devigo added a commit to devigo/AspNetCore.Docs that referenced this issue May 6, 2021
Rick-Anderson pushed a commit to dotnet/AspNetCore.Docs that referenced this issue May 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests