如何最好地对传递到我的控制器的数据实施 JWT 凭证的简单验证

How to best implement simple validation of JWT credential to data being passed to my controller

我的 ASPNetCore 网站 API 正在使用 JWT(Json 网络令牌)进行身份验证。 JWT 令牌内部有一个外部和内部用户 ID。在 JWT 中拥有这些 ID 与我无关,因为 JWT 无法被篡改或变得无效,并且内部 ID 在系统之外的任何地方都没有用。当然,密码不在JWT内容中。

在 JWT 中,外部用户 ID 成为用户的 System.Security.Claims.ClaimType.Name。内部 ID 设置为 JwtRegisteredClaimName.UniqueName 值。

当调用 Web API 时,[Authorize] 属性确保用户已通过身份验证并具有当前有效的 JWT 是很好的。我担心的是,一旦用户登录,就有机会通过使用 Web API 进行黑客攻击,发送外部或内部用户 ID 作为与当前经过身份验证的用户不匹配的标准。控制器中的一些 Web 方法接受内部用户 ID 作为发布请求的一部分,例如,保存用户信息的调用内部有内部用户 ID,用作保存数据的密钥。我需要确保经过身份验证的用户 matches/is 与通过 Web API 保存其数据的用户相同。

我的问题是如何以及在何处最好地在我的网络中实施此数据级安全性 api? 政策似乎无法应用于正在传递的数据。授权过滤器似乎无权访问消息正文或任何数据绑定。动作过滤器 (Microsoft.ASPNetCore.MVC.Filters) 运行 稍后,但看起来它们可能并不是真正用于此目的。此外,您如何访问在动作过滤器中发布的消息正文?或者我应该始终确保将用户 ID 作为我可以通过 ActionExecutingContext.ActionArguments?

访问的一致命名参数传递给方法

我搜索了很多帖子,但没有找到任何符合我正在尝试做的场景。

您始终可以使用 Middleware 在已填充 Response 对象时拦截调用,请参阅代码示例表格 here and here

授权过滤器也可以使用 EnableRewind 读取请求正文:

public class ReadableBodyStreamAttribute : AuthorizeAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var request = context.HttpContext.Request;
        context.HttpContext.Request.EnableRewind();
        using (var stream = new StreamReader(request.Body))
        {
            stream.BaseStream.Position = 0;
          var  requestBody = stream.ReadToEnd();
        }

    }
}

也适用于动作过滤器:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ReadableBodyStreamAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext actionContext)
    {
        var request = actionContext.HttpContext.Request;
        var route = request.Path.HasValue ? request.Path.Value : "";
        var requestHeader = request.Headers.Aggregate("", (current, header) => current + $"{header.Key}: {header.Value}{Environment.NewLine}");
        var requestBody = "";
        request.EnableRewind();
        using (var stream = new StreamReader(request.Body))
        {
            stream.BaseStream.Position = 0;
            requestBody = stream.ReadToEnd();
        }
        if (...)
        {
            var wrongResult = new { error = "Wrong parameters" };
            actionContext.Result = new JsonResult(wrongResult);
        }

    }
}