简体   繁体   中英

Filters for Azure Functions

Is it possible to have Filters (Auth or Exception) for Azure functions? I just want to not duplicate code to validate bearer token in every function. I see that there is a filter concept in webjobs sdk. https://github.com/Azure/azure-webjobs-sdk/wiki/Function-Filters

I want to only validate the bearer token before executing any function. So if filters are not the best option then is there any other better way to handle this situation ?

Depending on how feature rich you want your responses you could use function filtered but they are very limited at the moment until this issue has been completed - https://github.com/Azure/azure-webjobs-sdk/issues/1314

Alternatively, you could set up a pipeline in each of your functions so you could apply the same cross-cutting concern logic inside your function app. obviously this will be a lot more work but comes with a lot more flexibility.

Example - https://github.com/kevbite/AzureFunctions.GreenPipes

Instead of bringing in another package, you can just pass your function code as an argument in to a wrapper method.

//business logic
[FunctionName("PostWidget")]
public async Task<IActionResult> PostWidget(
  [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "widgets")] Widget item, HttpRequest req, ILogger log)
{
  return await _functionWrapper.Execute(req, item, async () =>
  {
    log.LogInformation($"posting widget: ${item.Id}");

    var newItem = await dbContext.Widgets.AddAsync(item);
    await dbContext.SaveChangesAsync();

    return new ResponseEnvelopeResult<Widget>(HttpStatusCode.Created, newItem.Entity);
  });
}

//functionWrapper class
public async Task<IActionResult> Execute(T model, HttpRequest req, Func<Task<IActionResult>> azureFunction)
{
  var results = await _validator.ValidateAsync(model, ruleSet: $"default,audit,{req.Method}");
  if (!results.IsValid)
  {
    var errors = results.Errors.Select(x => x.ErrorMessage).ToList();
    _log.LogWarning($"Model validation failed for type '{typeof(T).Name}'. Validation errors: [{errors.Join()}] ");
    return new ResponseEnvelopeResult<T>(HttpStatusCode.BadRequest, null, errors);
  }

  try
  {
    return await azureFunction();
  }
  catch (Exception e)
  {
    _log.LogError(e, "Unhandled exception occured in FunctionWrapper");
    return new ResponseEnvelopeResult<T>(HttpStatusCode.InternalServerError, null, new[] { e.Message });
  }
}

Then your wrapper can be setup to do validation, retrieve user info, etc. If you need items passed back to your function layer, you can easily do so without obscuring your function intent. I've got a large example of this implementation on my blog.

https://blog.bruceleeharrison.com/2019/09/04/azure-v2-functions-with-fluentvalidation/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM