Azure-webjobs-sdk: Allow an IFunctionFilter to modify the HTTP status code/response

Created on 2 Aug 2020  路  8Comments  路  Source: Azure/azure-webjobs-sdk

IFunctionFilter (and in particular IFunctionInvocationFilter) seems to be the only mechanism by which the execution pipeline of a function can be modified in a cross-cutting way (since you can't really access the host builder to add arbitrary middleware).

As such, it would be very useful if the filters could affect the resulting status code of a request (say in an HTTP-triggered function).

A concrete example would be checking for certain headers or access token claims, to determine if the caller has the right permissions for the invocation, and return a 401 or 403 as appropriate.

Currently, the only way to stop/abort the processing of the current request is to throw an exception from the filter, but this results in a fixed 500 error reported to the client.

Potential solutions

  • Special-case a new HttpFunctionException which can provide a status code and optional status string/message, and in this case it would not be reported as a function failure.
  • Extend the FunctionExecutingContext to allow the filter to signal whether further processing should happen or if it should be stopped (and with that HTTP status code result)

Potential issues

It's obvious that not all function invocations are HTTP-triggered, so maybe this should only be applied to those. There would need to be a mechanism in the filter to check the type of function being invoked. Currently the FunctionFilterContext is not sufficiently expressive to accomodate general-purpose pipelines that can act differently depending on the current invocation features/metadata/descriptor. Perhaps the IFunctionExecutionFeature should be exposed somehow? Maybe just the FunctionDescriptor?

Feature

All 8 comments

@mhoeger should issues related to APIs implemented in the webjobs-sdk be reported in that repo? (such as this one: https://github.com/Azure/azure-webjobs-sdk/issues/1314)

@mathewc / @fabiocav / @paulbatum - This is a request similar to https://github.com/Azure/azure-functions-host/issues/4927 and others on adding some sort of filters to simplify logic for cross-cutting concerns.

Marking as Triaged and as a feature

You could inject IHttpContextAccessor into your IFunctionFilter implementation.
The property HttpContext should allow you to modify the response.
Kind regards

@stephanruhland but then how would u cancel the execution of the function ina way that wouldn't override the response as throwing an exception makes it a 500

  1. Implement a custom exception, like for example an _AbortRequestException_.
  2. Check your custom logic in the _IFunctionInvocationFilter_ or _IFunctionInvocationAttribute_ implementation and throw your abort exception.
  3. In the implementation of the interface _IFunctionExceptionFilter_ it can be checked if it is a Http function (httpContextAccessor.HttpContext != null) that is the source of the exception and if it is your abort exception. If yes, you can modify the response.

In that example the main part of your function should not be executed.
Its just an idea :)

Kind regards

@stephanruhland , I would very much like to use your idea. However, isn't IFunctionInvocationFilter obsolete? I am running Azure Functions 3 and when I go to implement it, visual studio let's me know that is obsolete.

Yes, its marked as obsolete but i think they want to update and remove the obsolete attribute. It says only "preview" and not outdated code. Im dont know another "better" solution for now, so that was my way to go.

[System.Obsolete("Filters is in preview and there may be breaking changes in this area.")]
public interface IFunctionInvocationFilter : Microsoft.Azure.WebJobs.Host.IFunctionFilter
  1. Implement a custom exception, like for example an _AbortRequestException_.
  2. Check your custom logic in the _IFunctionInvocationFilter_ or _IFunctionInvocationAttribute_ implementation and throw your abort exception.
  3. In the implementation of the interface _IFunctionExceptionFilter_ it can be checked if it is a Http function (httpContextAccessor.HttpContext != null) that is the source of the exception and if it is your abort exception. If yes, you can modify the response.

In that example the main part of your function should not be executed.
Its just an idea :)

Kind regards

Can you suggest how can we abort the exception in IFunctionExceptionFilter?

Was this page helpful?
0 / 5 - 0 ratings