【问题标题】:Identity server API Policy and roles身份服务器 API 策略和角色
【发布时间】:2018-08-08 02:35:58
【问题描述】:

我们目前有一个使用 Identityserver4 2.0 构建的身份服务器。我们正在向我们的 API 添加一些政策指南。看了很多教程,主要是这个Policy-Based Authorization in ASP.NET Core

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddAuthorization(options =>
    {
        options.AddPolicy("RequireElevatedRights", policy => policy.RequireRole("SuperAdministrator", "ChannelAdministrator"));
    });
}

[Authorize(Policy = "RequireElevatedRights")]
public class ChannelAdministrationController: Controller
{
}

我认为我们对如何做到这一点有一些误解。据我了解,我们的 API 将检查当前用户的授权并围绕它制定政策。基本上我们正在检查用户在标头中发送的令牌是否正确?

我的问题是用户是否在创建令牌后更改了权限。鉴于访问令牌有效期为 1 小时并且刷新令牌不会过期。这是否意味着拥有有效令牌的用户仍然可以在一个小时内访问东西?

我们如何确保当前经过身份验证的用户实际上仍然有权执行声明中的操作?

【问题讨论】:

  • 这就是为什么将权限放入令牌是一个坏主意(除其他外)。 policyserver.io
  • @leastprivilege 看到这就是我们一直在等待的我还没有看到你们上传了开源项目。

标签: security asp.net-core oauth permissions identityserver4


【解决方案1】:

这是 (jwt) 令牌的要点,您不必针对每个请求访问数据库。

身份令牌(长寿命令牌)和访问令牌(短寿命,授权相关数据。

身份令牌应仅包含很少更改且与用户身份相关联的声明(用户名、名字 + 姓氏、生日、电子邮件、email_verified 等)。

如果您期望经常更改,请不要放置“管理员”之类的角色。

授权(是否允许用户 A 创建这个和那个,或读取/查看资源)应该在一个单独的(每个服务)数据库中完成,然后您从那里获取它(并在必要时缓存)。

您的替代方案,如果您确实已将此类“权限”放入令牌中,或者有需要立即生效的情况(帐户受损或解雇工人),那么您可以撤销令牌。

但请记住,撤销端点仅适用于刷新和引用(也称为不透明)令牌。

您无法立即撤销 JWT 令牌。当然,您可以在生成令牌时将其放入内存缓存(redis,本地缓存)中时将唯一(和随机)的 id 放入令牌的过期时间。

在每个请求中,您都会检查该 id 是否仍在缓存中。如果它在那里并且令牌有效,则允许访问。否则否认。

当您进行一些敏感更改时,将一条消息发送到您的消息总线(rabbitmq、azure queues、redis),触发一个处理程序,该处理程序从缓存中删除该 id,并且在下一次请求时,该值在缓存并拒绝访问

【讨论】:

  • 我的部分问题是权力。要我把所有东西都放进令牌里。我们正在拆分一个非常大的 api,他们担心每次检查数据库以获取用户访问权限会使事情过载,这就是他们想要在令牌中使用它的原因。我反对这一点,因为我不能接受被删除访问权限的人仍然可以访问一个小时。
  • 您可以使用本地(或分布式)内存缓存来存储权限。您还需要一个基于消息的系统来在权限更改时使此内存缓存失效(因为有人编辑了它们)。但是在令牌中包含所有东西是很糟糕的,至少如果您使用的是 jwt 令牌。
  • 唯一应该在令牌 imho 中的是角色(如果更改频率很低并且不需要立即失效)和范围,它们告诉用户是否可以访问 api 在全部(即scope: ["order", "profile"],用户可以使用它访问订单或配置文件webapi。如果他没有“订单”范围,则在尝试访问订单API时,他只会被拒绝。但如果你想检查如果用户有权订购特定商品或取消订单,则应在每个服务基础和权限系统上完成(+缓存,如果性能成为问题)
  • 还可以阅读Identity vs Permissions,尤其是“声明应该模拟用户的身份,而不是权限
  • 你会验证我已经知道的一切。现在我只需要学会更好地解释它。您不会相信我们在声称目前它被用作数据存储 IMO 中的内容。我担心我们很快就会达到 JWT 的大小限制
【解决方案2】:

虽然我的回答可能不如评论和曾的前一个那么深刻,但我对此进行了一些实验,并采取了稍微不同的方法。

我被要求将角色转储到颁发的令牌中,是的,你是 100% 正确的,除非令牌被更新(我的情况是 1 小时),如果 api 服务器不是,他们可以访问 1 小时或更长时间被任何呼叫击中。

我的解决方法有两点:

  • 对 API 服务器进行强制命中以验证用户(每 60 秒)
  • 一旦用户的角色在 identityserver4 上发生更改,就会为用户实施令牌擦除

这可能不是漂亮的解决方案,但它意味着超级管理员更改您的角色的那一刻,它会从数据库存储中擦除用户令牌(如果有的话)。 前端会在 60 秒后(或者在调用之前)访问 api 服务器,迫使用户再次重定向到登录页面以获取新令牌。

这意味着在最坏的情况下,用户在其令牌被擦除后可以访问 60 秒。

不是最干净的解决方案,但为实验做了诀窍。

【讨论】:

    猜你喜欢
    • 2012-07-10
    • 2013-07-24
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 2022-09-24
    • 1970-01-01
    相关资源
    最近更新 更多