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

Complete Invocation Filters Feature #1284

Closed
5 tasks
mathewc opened this issue Aug 8, 2017 · 41 comments
Closed
5 tasks

Complete Invocation Filters Feature #1284

mathewc opened this issue Aug 8, 2017 · 41 comments
Assignees
Labels
Feature: Function Filters Request for Function Filters to be a supported feature
Milestone

Comments

@mathewc
Copy link
Member

mathewc commented Aug 8, 2017

For WebJobs v2, bulk of the work for Invocation Filters was checked in via #980. However, there are some remaining work items we're tracking before the feature can be considered complete:

  • Integrate Filters fully with DI
  • Allow filters to provide a response (tracked by Allow Invocation Filters to Short Circuit / Provide Response #1314)
  • Make filter Timeout behavior consistent. Currently only invocation filters run under timeout, not exception filters
  • Consider adding IBinder to the execution context to facilitate binding operations in filters
  • Add Verbose trace statements when executing filters?

In v3 the Filters feature is currently marked Obsolete due to the above issues: #1912. The feature is not going away - we applied Obsolete because we had to GA v3 before the feature was complete, so we wanted to convey that there may be breaking changes in this area as we complete the work above.

@mathewc mathewc self-assigned this Aug 8, 2017
@mathewc mathewc added this to the Sprint 4 milestone Aug 9, 2017
@MikeStall
Copy link
Contributor

We should split "Finalize design for FunctionResultException" into a separate work item.

@mathewc
Copy link
Member Author

mathewc commented Aug 22, 2017

@MikeStall - Moved the Result work out into its own issue here: #1314

@mathewc mathewc modified the milestones: Sprint 5, Sprint 4 Aug 24, 2017
@paulbatum paulbatum modified the milestones: Sprint 5, Next Aug 28, 2017
@mathewc mathewc changed the title Invocation Filters Remaining work Complete Invocation Filters Feature Oct 4, 2018
@chris-rogala
Copy link

Has there been any progress on this? I noticed FunctionInvocationFilterAttribute is still marked Obsolete ("..in preview..."). Any idea when it will be finished up?

@ashkansirous
Copy link

Yeah! Very strange that it is taking this long. Is it because of the latest changes on DI forAzure functions?
https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection
I just love the part that it says:
Microsoft.NET.Sdk.Functions package version 1.0.28 or later
And version 1.0.28 is the latest version and is only 25 days old :)
I hope it means that we get this feature soon as well

@mathewc
Copy link
Member Author

mathewc commented Jun 7, 2019

Yes, we want to finish the feature up properly, integrating it with the new DI work naturally. The feature was marked Obsolete because we anticipated there might be some breaking changes as we finished it up. I'd like to complete this in the next major release. @fabiocav

@kspoojary
Copy link

Any update on this? When is the next Major release?

@vitalybibikov
Copy link

Will it be implemented in 3.0 version?

@AvinashRamalingam
Copy link

Any update on this feature? Will this be part of V3?

@iamalexmang
Copy link

Any updates on this feature?

@fabiocav
Copy link
Member

This feature has not been prioritized as part of the 3.0 work. This is not currently part of the immediate roadmap, so we don't have an ETA we can share.

/cc @mathewc @mattchenderson

@iamalexmang
Copy link

Thanks for the update @fabiocav.
Reason for why I'm looking for a filter right now is in fact to have a custom authorization done before the function code gets called. Specifically, I want to implement a role authorization provider and validate that an authenticated user is indeed allowed to call a particular function in a function app.
Since filters are, due to their lack of tread-safe nature, a no-go, is there another way in which this can be achieved?

@KenBonny
Copy link

That's too bad because this is something useful that I would like to see in the platform.

@BKB503
Copy link

BKB503 commented May 14, 2020

any update on this?

@IanKemp
Copy link

IanKemp commented Jun 1, 2020

Seems like the lack of update indicates that this feature is dead.

@davidpeden3
Copy link

Can anyone elaborate on what "Integrate Filters fully with DI" means? What integration is missing? Thanks.

Filters are not constructed using DI. I.e., you must use service location to "inject" dependencies into them.

@NSouth
Copy link

NSouth commented Aug 23, 2020

@davidpeden3 , thank you. I'll note here a few observations about global filters for others who are interested.

  1. It seems IFunctionFilter must be registered as a Singleton. You get a runtime error otherwise.
  2. Other Singleton services can be injected.
  3. If you want access to non-Singleton services, you need to inject IServiceScopeFactory and create a scope to resolve such services.
    Here is an example of what works from my testing:
    In Startup:
services.AddSingleton<IFunctionFilter, MyFunctionFilter>();
services.AddSingleton<IOtherService, OtherService>();
services.AddTransient<ITransientHelper, TransientHelper>();

In MyFunctionFilter:

public class MyFunctionFilter : IFunctionInvocationFilter
{
	private readonly IServiceScopeFactory _serviceScopeFactory;
	private readonly IOtherService _otherService;

	public MyFunctionFilter(IServiceScopeFactory serviceScopeFactory, IOtherService otherService)
	{
		_serviceScopeFactory = serviceScopeFactory;
		_otherService = otherService
	}
	
	public async Task OnExecutingAsync(FunctionExecutingContext executingContext, CancellationToken cancellationToken)
	{
		await _otherService.DoSomething();
		using (var scope = _serviceScopeFactory.CreateScope())
		{
			var helper = scope.ServiceProvider.GetRequiredService<ITransientHelper>();
			// use helper
		}
	}
	
	public Task OnExecutedAsync(FunctionExecutedContext executedContext, CancellationToken cancellationToken)
	{
		throw new NotImplementedException();
	}	
}

@vijaymarada
Copy link

Following this.
After reading all of them. Even the Microsoft is made IFunctionInvocationFilter, IFunctionExceptionFilter obsoleted I feel, Its safe to use for the basic support of global exception handling and authorizing the requests for my HTTP trigger function.
@mathewc @paulbatum Any suggestions?

@MrMaheshwari
Copy link

Why this is not based on attribute?

@NSouth
Copy link

NSouth commented Aug 26, 2020

@MrMaheshwari, I haven't tried it myself, but I believe you can implement invocation filters as attributes. See the example here:
https://www.c-sharpcorner.com/article/do-you-know-azure-function-have-function-filters/

@MrMaheshwari
Copy link

@MrMaheshwari, I haven't tried it myself, but I believe you can implement invocation filters as attributes. See the example here:
https://www.c-sharpcorner.com/article/do-you-know-azure-function-have-function-filters/

Thanks for sharing such a nice article

@MrMaheshwari
Copy link

Any ETA to release this feature?

@MrMaheshwari
Copy link

MrMaheshwari commented Aug 27, 2020

@MrMaheshwari, I haven't tried it myself, but I believe you can implement invocation filters as attributes. See the example here:
https://www.c-sharpcorner.com/article/do-you-know-azure-function-have-function-filters/

@NSouth Here is a limitation, we can not return back the HttpResponseMessage object

@IanKemp
Copy link

IanKemp commented Aug 31, 2020

Microsoft Azure dev team: issues "preview" of highly-requested feature
Also Microsoft Azure dev team: doesn't bother finishing said feature more than 3 years later

Have you guys, you know, considered hiring more devs so work actually gets done in a reasonable timeframe? It's not as if you work for a small mom-and-pop shop...

@jeffhollan
Copy link

I can see some interest in this and so going to give the answer that may help folks plan the best, but things can always change. We don't have any plans to bring functions filters as currently implemented as this preview feature forward. That said, the scenario that many people are interested in using function filters for, namely to add some logic and middleware before an execution triggers, is something we do want to solve for. We have recently prototyped some features as part of the upcoming out of process .NET work that allows users to add some middleware to execute before a function triggers for something like token validation or whatnot. If you were to ask me today that's what I would say is the future of this scenario, and not function filters as implemented.

I'm happy to keep this issue open to continue discussion around it, but don't want folks to hold out thinking we are holding out and waiting to move this from preview to GA. There were always some tradeoffs with the approach we took with filters and we feel we may be able to provide the benefits in a more flexible way with something like middleware.

// @anthonychu as FYI who is helping PM these features.

@IanKemp
Copy link

IanKemp commented Sep 10, 2020

We have recently prototyped some features as part of the upcoming out of process .NET work that allows users to add some middleware to execute before a function triggers for something like token validation or whatnot. If you were to ask me today that's what I would say is the future of this scenario, and not function filters as implemented.

Honestly, that's exactly how I'd want it to work.

Not to be a downer or fail to give credit where it's due to you guys for your efforts, but for better or worse the ASP.NET Core "way" of doing dependency injection, middleware, etc. is effectively the standard in the .NET world, and Azure Functions' differences (seemingly at times just for the sake of being different) and limitations compared to ASP.NET Core have always frustrated me.

Converging Azure Functions towards the way that ASP.NET Core works is probably the best decision that could be made in terms of helping adoption and maintainability. In an ideal world, I'd love to be able to write an ASP.NET Core web API application - then simply add an Azure Functions NuGet package(s), annotate the endpoints with attributes from that package, and when I press F5 in Visual Studio, func.exe launches instead of Kestrel. If I remove the package and attributes, the app goes back to being a standard web API.

@MisinformedDNA
Copy link

Yes. Yes. A million times Yes. At its core, Azure Functions should just be an ASP.NET Core app with an extra service (plus configuration), i.e.:

services.AddAzureFunctions(options => { ... });

@lambdakris
Copy link

@jeffhollan @anthonychu is there somewhere where work on middleware is being planned or tracked?

@niksanla2
Copy link

@jeffhollan where is our middleware?

@MartinWickman
Copy link

MartinWickman commented Mar 29, 2021

It might be worth noticing that Azure Function in .NET 5 will have support for middleware directly. My guess would be that supporting both approaches might not be in the pipeline for the future, though I don't know of course

@david-peden-q2
Copy link

@MartinWickman Middlewares definitely help out with cross-cutting concerns, although they currently lack any real substance right now to make them useful. E.g., no access to the request/response and no ability to terminate the pipeline.

Also, they don't really make sense as a replacement for filters that are intended to be applied to a specific function (e.g., an authorization-type filter).

@bbrandt
Copy link

bbrandt commented Nov 17, 2021

We have HTTP endpoints in Azure Functions that use Durable Functions. What is the path forward for middleware or something to check a JWT bearer token when the HTTP endpoint is called?

@rowanfreeman
Copy link

rowanfreeman commented Apr 19, 2022

This feels like a desperately needed feature. It's now 2022 and this is still unresolved since 2017. I have a function app with 3 HTTP functions and more on the way soon.

I'm using model binding rather than the clunky and unnecessary HttpRequest. i.e.

public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] Request request, ILogger logger)

This works, but the downside is that if the incoming request is in an invalid format (i.e. bad JSON), the function returns server 500 and nothing else.

I'm trying to catch JSON serialisation errors so that I can return a 400 Bad Request and helpful message (i.e. what part/path of the JSON request is invalid).

To do this with a HttpRequest object in every function seems a bad and duplicated way to do it. I'd rather just catch exceptions of a certain type with a filter and return a 400.

@ben-graffle
Copy link

Is there any update on this?

@davidpeden3
Copy link

not sure why @mathewc hasn't officially updated this thread but it appears that this feature is doa:

image

@ben-graffle
Copy link

Sounds good, thanks for the prompt response.

-Ben

@mathewc
Copy link
Member Author

mathewc commented May 5, 2022

Thanks. Yes the issue referenced above states our position on this feature.

@mathewc mathewc closed this as completed May 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Function Filters Request for Function Filters to be a supported feature
Projects
None yet
Development

No branches or pull requests