【问题标题】:Handling authorization with IdentityServer4使用 IdentityServer4 处理授权
【发布时间】:2020-10-28 07:59:22
【问题描述】:

我对如何使用具有身份验证和授权的集中式 IDP 感到非常困惑。我的项目的架构是一个单一的 Web API 和一个 React 客户端。我想将事物结构化到微服务中,只是为了尝试更现代的东西,但我在集中式身份方面遇到了重大问题,就像许多其他人一样。

我的目标相当简单。用户登录,从他们有权访问的租户列表中选择一个租户,然后将他们重定向到具有角色和“tid”或租户 ID 声明的客户端,这只是所选公司的 GUID。

Microsoft 规定的在我的场景中添加身份的方法是 IdentityServer,所以我从它开始。一切都很顺利,直到我发现了代币的内部运作。虽然其他一些人在添加权限时遇到问题,但我的应用程序中的授权逻辑非常简单,角色就足够了。虽然我最初可以通过到期自然刷新角色,但每当我的用户选择不同的租户“登录”到时,它们必须立即更新。但是,问题是当用户更改租户而不注销时,我无法刷新这些声明。本质上,我尝试将授权与身份验证混合使用,结果碰壁了。

看来我有两个选择:

  1. 从单独的提供者,甚至身份服务器本身的端点获取授权信息,例如 /user-info,但用于授权信息。这最终会增加巨大的开销,但服务器和客户端的实际样板是最小的。这和 OSS 版 PolicyServer 的做法类似,虽然我不知道他们的付费实现如何。我的主要问题是客户端和资源(API)都需要这些信息。如何避免每次交互 N 个请求(其中 N 是资源/客户端的数量)?
  2. 实现某种自定义状态并保留需要刷新 JWT 的用户存储。检查这些并向调用者返回一些自定义响应,然后调用者使用自定义 js 客户端代码刷新此响应上的令牌。这是一个巨大的理论,即使它是合理的,仍然会引入状态,并且在需要大量自定义代码的同时使 JWT 的观点无效。

所以,我为这篇长文道歉,但这真的让我很恼火。我不需要使用 IdentityServer 或 JWT,但我希望至少有一个 React 前端。对于最新的租户选择和角色,我有哪些选择?就在我愿意让步并实现一个返回新数据的授权端点时,我意识到我会在 API 和客户端 每个 请求中调用它。即使有缓存的数据,这在纯 http 调用中也是很多开销。是否有一些替代解决方案可以在这里工作?老实说,我是否可以只使用具有安全且仅在必要时更新的授权信息的 cookie?

【问题讨论】:

    标签: asp.net-core jwt authorization identityserver4 identity


    【解决方案1】:

    任何人都想知道我最终是如何做到这一点的,这是一个很长的故事,但我最终只是根据其他人所说的和准则来分离权限。门户概念行不通,因为我不知道如何“软”注销用户,在操作后刷新他们的令牌,而不会脱节或让他们再次输入凭据。

    我最终使用远程 gRPC 调用进行授权。你可以在https://github.com/Perustaja/CoreMultiTenancy查看更多信息

    【讨论】:

      【解决方案2】:

      当您想按原样使用 IdentityServer 进行用户授权时,这会变得令人困惑。将顾虑分开。

      作为多米尼克·拜尔的commented

      是的——我们建议使用 IdentityServer 进行最终用户身份验证, 联合和 API 访问控制。

      PolicyServer 是我们推荐的用户授权。

      选项 1 似乎是推荐的选项。因此,如果您决定选择选项 1:

      PolicyServer 的 OSS 版本足以处理请求。但不是使用json config file

      // this sets up the PolicyServer client library and policy provider
      // - configuration is loaded from appsettings.json
      services.AddPolicyServerClient(Configuration.GetSection("Policy"))
          .AddAuthorizationPermissionPolicies();
      

      从端点获取信息。添加缓存以提高性能。

      为了允许集中访问,您可以创建单独的策略服务器或使用用户授权端点扩展 IdentityServer。使用extension grants 访问用户授权端点,因为您可能想区分客户端和api。

      json 配置是本地的。新端点将需要它自己的数据存储,它可以在其中读取用户声明。为了允许集中信息,请添加有关可以在何处使用权限的信息。我个人使用范围来建模权限,因为客户端和 api 都知道范围。

      最后一步是添加管理 UI 或端点以维护用户授权。

      【讨论】:

      • 似乎真正的问题是存储 JWT 状态以强制刷新与调用每个请求以检索授权信息。第一个看起来很老套,第二个似乎效率低下。我并不真正担心完成请求的时间,只是担心服务器上的负载。我刚刚将我的电话增加了两倍,但第二个选项仍然看起来很老套,并且与 JWT 的观点背道而驰。
      • @perrustaja 我稍后会更新答案,但现在:在我的设置中,JWT 不包含用户授权声明。用户授权有不同的来源。因此没有理由存储 JWT 状态,因为用户(身份)和客户端授权不会改变。即使上下文发生变化,例如不同的租户,用户授权不会改变。只有用户授权的视图会发生变化。您可以通过添加一个鉴别器,即租户来管理它。
      • 我明白了,你认为应该如何添加鉴别器?我目前的计划是当用户访问门户时,它会设置其 SelectedOrg 属性。在 SPA 中的每个页面加载时,它使用 id_token 的子 GUID 调用授权信息端点(角色、权限、选定的组织)。一旦获得此信息,就会向 someapi/organizations/{selectedorg}/... 发出后续请求,这会处理一些边缘情况,但我个人的理想是支持多选项卡,因此用户可以在一个选项卡和另一个选项卡中拥有 1 个租户的数据下一个。这部分对我来说似乎完全基于客户。感谢反馈
      猜你喜欢
      • 2017-10-15
      • 2017-10-10
      • 2020-11-29
      • 1970-01-01
      • 2018-01-31
      • 2021-07-10
      • 1970-01-01
      • 2017-02-04
      • 1970-01-01
      相关资源
      最近更新 更多