Azure Functions 的筛选器
Filters for Azure Functions
是否可以为 Azure 函数设置过滤器(Auth 或 Exception)?我只是不想在每个函数中重复代码来验证不记名令牌。我看到 webjobs sdk 中有一个过滤器概念。 https://github.com/Azure/azure-webjobs-sdk/wiki/Function-Filters
我只想在执行任何功能之前验证不记名令牌。因此,如果过滤器不是最佳选择,那么还有其他更好的方法来处理这种情况吗?
根据您希望回复的功能有多丰富,您可以使用过滤功能,但目前它们非常有限,直到此问题完成 - https://github.com/Azure/azure-webjobs-sdk/issues/1314
或者,您可以在每个函数中设置一个管道,这样您就可以在函数应用程序中应用相同的横切关注点逻辑。显然,这将需要更多的工作,但会带来更多的灵活性。
无需引入另一个包,您只需将函数代码作为参数传递给包装器方法即可。
//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 });
}
}
然后您的包装器可以设置为执行验证、检索用户信息等。如果您需要将项目传递回您的功能层,您可以轻松地做到这一点,而不会混淆您的功能意图。我的博客上有一个关于此实现的大型示例。
https://blog.bruceleeharrison.com/2019/09/04/azure-v2-functions-with-fluentvalidation/
是否可以为 Azure 函数设置过滤器(Auth 或 Exception)?我只是不想在每个函数中重复代码来验证不记名令牌。我看到 webjobs sdk 中有一个过滤器概念。 https://github.com/Azure/azure-webjobs-sdk/wiki/Function-Filters
我只想在执行任何功能之前验证不记名令牌。因此,如果过滤器不是最佳选择,那么还有其他更好的方法来处理这种情况吗?
根据您希望回复的功能有多丰富,您可以使用过滤功能,但目前它们非常有限,直到此问题完成 - https://github.com/Azure/azure-webjobs-sdk/issues/1314
或者,您可以在每个函数中设置一个管道,这样您就可以在函数应用程序中应用相同的横切关注点逻辑。显然,这将需要更多的工作,但会带来更多的灵活性。
无需引入另一个包,您只需将函数代码作为参数传递给包装器方法即可。
//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 });
}
}
然后您的包装器可以设置为执行验证、检索用户信息等。如果您需要将项目传递回您的功能层,您可以轻松地做到这一点,而不会混淆您的功能意图。我的博客上有一个关于此实现的大型示例。
https://blog.bruceleeharrison.com/2019/09/04/azure-v2-functions-with-fluentvalidation/