在哪里可以添加权限要求的日志记录范围,而无需重复自己?

Where can I add a logging scope for permission requirements without repeating myself?

提问人:Ben Zuill-Smith 提问时间:11/10/2023 最后编辑:marc_sBen Zuill-Smith 更新时间:11/10/2023 访问量:18

问:

在 .NET 6 中,我添加了一个授权策略,用于确保用户有权访问一组特定的资源。现在,我想记录资源集的 ID 以及用户 ID,以显示哪个用户访问或修改了哪个资源集。并非所有端点都需要此日志记录范围,只有那些具有策略要求的端点(路由 )。[Authorize(Policy = "MyResourcePolicyName")]

我想必须有一个地方可以放置此代码,这样我就不必在每个端点上添加此日志记录范围。我在哪里做?这似乎不是正确的位置,因为没有用范围包裹它来拨打电话。是否有其他层可以添加日志记录范围?或者我可以在中间件级别做些什么,知道何时应用需求?AuthorizationHandler.HandleRequirementAsync(ctx, requirement)next()

asp.net-core-6.0

评论


答:

0赞 Ben Zuill-Smith 11/10/2023 #1

我相信我找到了一个解决方案。在 之后和之前放置一个中间件函数。此中间件可以检查端点的元数据,以确定应用的策略并将上下文推送到记录器上。app.UseAuthorization()app.UseEndpoints()

public async Task Invoke(HttpContext context)
{
    // Check if the request requires authorization (you can customize this logic)
    var metadata = context.GetEndpoint()?.Metadata.GetMetadata<Microsoft.AspNetCore.Authorization.IAuthorizeData>();

    if (metadata != null && metadata.Policy == "MyPolicyName")
    {
        string userId = context.User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value;

        using (LogContext.PushProperty("UserId", userId))
        using (LogContext.PushProperty("ResourceSetId", context.Request.Headers["ResourceSet"]))
        {
            await _next(context);
        }
    }
    else
    {
        // Continue without pushing properties
        await _next(context);
    }
}