【问题标题】:JWT "self" authentication in Net Core 2.2 MVC WebApiNet Core 2.2 MVC WebApi 中的 JWT“自我”身份验证
【发布时间】:2019-12-24 01:12:47
【问题描述】:

我想通过某种“自我”策略来提高 API 的安全性,以验证对某些用户操作(如 DELETE 用户)的调用是由向其颁发令牌的同一用户发出的。有没有办法以类似于policy based authorization 的方式做到这一点?

我有一个在 Kestrel 上运行 MVC WebAPI 的 .Net Core 2.2。我有用户、角色和用户角色,并且我有启用角色的基于令牌的身份验证。我可以发出令牌,然后使用控制器中的“授权”属性进行验证。但是,我一直在寻找一种方法来验证对用户的某些操作仅由用户自己进行,一种“自我”身份验证策略来验证,例如,用户 3 正在尝试删除用户 3,并且只有用户 3 . 我已经挖掘了声明和所有内容,我知道我可以制作一个简单的服务来传递声明并验证它,但我想以一种类似于基于策略或基于角色的身份验证的更顺畅的方式来完成它。我不知道我是否可以使用某种中间件或其他东西来制作它,但能够让它尽可能干净会很棒。

[编辑]

主要目的是避免用户删除其他用户创建的资源,使他们只能删除自己创建的资源。

[Edit2 - 解决方案] 感谢Paul Lorica's Answer,我现在可以描述我是如何做到的。

首先是创建一个 Requirement 和一个 Handler 类似于 Microsoft 在文档中提供的示例。我们所做的是将声明添加到我们拥有的令牌生成方法/服务中,并将 ID 添加为 NameIdentifier。之后,我们在处理程序中注入 IHttpContextAccessor。然后我们可以验证请求中的ID是否与Claim中的ID相同。所以这很容易。

我正在添加逻辑示例以使其正常工作。

PS:将 IHttpContextAccessor 作为单例注入到启动类中,否则将不起作用。

处理程序:

public class SelfUserHandler: AuthorizationHandler<SelfUserRequirement>
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        public SelfUserHandler(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                       SelfUserRequirement requirement)
        {
            if (!context.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier))
            {
                return Task.CompletedTask;
            }

            var nameIdentifier = context.User.FindFirst(c => c.Type == ClaimTypes.NameIdentifier).Value;

            if (_httpContextAccessor.HttpContext.Request.Path.ToString().ToUpper().Contains(nameIdentifier.ToUpper()))
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }



            return Task.CompletedTask;
        }
    }

要求

public class SelfUserRequirement : IAuthorizationRequirement
    {
        public SelfUserRequirement() { }
    }

附加信息: 内特·巴贝蒂尼 回答here Joe Audette 回复here

【问题讨论】:

  • 您能否详细说明一下您的示例:“用户 3 正在尝试删除用户 3,并且仅删除用户 3”?用户只能删除自己创建的资源?
  • @RamKumaran 是的。用户只能删除自己创建的资源。这是主要目的,避免用户删除不是自己创建的资源。
  • 只需在业务层中添加逻辑以检查登录用户,并确定他们是否可以“执行”您想要的操作。

标签: c# asp.net-mvc asp.net-web-api .net-core jwt


【解决方案1】:

首先,当您的代码根据策略进行验证时,策略不了解,也不需要知道您在做什么。

我想您可以通过 URL 检索上下文。所以说如果它是一个删除用户/3

然后您可以创建一个策略来检查用户声称其 ID == 3。

在此处查看有关创建策略和访问 httpContext 的文档

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2

它有点幼稚的检查,我宁愿把这个逻辑放在控制器的方法中。

【讨论】:

  • 谢谢,这看起来差不多了。我可以从“NameIdentifier”声明中获取 ID,并且我正在使用此策略的空白要求,因为我不知道如何将请求 DELETE user/3 中的“3”传递给策略要求。所以,现在的问题是:有没有办法将 Id 传递给策略,以便我可以根据令牌声明进行验证?还是作为其要求的参数?
  • 好的,非常感谢您的建议。我最终做了一个 Requirement 和一个 Handler 并将 IHttpContextAccessor 注入到处理程序中,在那里我可以从请求中获取 ID 并检查 nameIdenfier 是否与请求中的 Id 相同。差不多吧。我会将所有代码都放在问题中,这样就很清楚了。谢谢!!
猜你喜欢
  • 2019-09-06
  • 2018-09-02
  • 1970-01-01
  • 2019-10-30
  • 2019-09-01
  • 2020-07-23
  • 2018-01-07
  • 2017-09-11
  • 2018-06-22
相关资源
最近更新 更多