从未授权的 Identity Server 4 请求 API 资源

3

我正在尝试使用Identity Server 4中的API资源,但认为我还有一些不理解的地方。

我有一个单页应用程序客户端,需要通过IdP对用户进行身份验证,然后代表该用户向API资源发出授权请求。该API没有作用域,因此我已在Identity Server中定义了与API资源相关联的一些API声明,但是没有为此资源定义任何作用域或作用域声明。

然而,现在我对如何在OIDC流程中请求访问此API资源感到困惑。通常我会在授权请求中使用作用域,但在这种情况下,我没有要使用的作用域。因此,在我实现IProfileService时,当我构建要返回的声明时,context.RequestedResources.ApiResources是空的。

那么,请求提供对无作用域API资源访问权限的令牌的正确流程是什么?我相信我在这里缺少了一些基础知识,并且可能会出乎意料地显得很愚蠢。但他们说没有愚蠢的问题,对吧?

2个回答

6

从4.0.2版本开始,还需要定义ApiScopes。我花了几个小时来弄清楚这一点。因此,例如使用InMemory时,需要定义ApiResources、ApiScopes和clients。否则,将不会为API资源定义范围。


1
我遇到了同样的问题,为什么我必须定义ApiScopes,当它们已经在ApiResources中定义了。 我目前看不出定义ApiResources的任何好处,而不是只使用ApiScopes。也许有人可以在最佳实践方面提供帮助。 - Michael Brunner
@MichaelBrunner 我认为资源中的作用域只是将作用域与资源关联起来,实际上并没有声明作用域,因此您需要单独声明它们,但这只是我的猜测。 - Glass Cannon
@GlassCannon 我自己找到了一些解决方案:
  • ApiResources 用于捆绑作用域以定义受众
  • 为了让我们更容易,为什么不使用“Rich enums”在代码中定义它们(DTO的静态只读实例与反射一起查找所有实例)。这样可以避免在各处使用字符串。
- Michael Brunner

6

作用域是资源(某个部分)功能的逻辑名称。因此,没有作用域的资源意味着该资源没有任何功能。这就是为什么资源应该至少有一个作用域。当客户端请求作用域时,实际上请求了某个功能的特定部分。

这也在文档中有所说明,尽管这并不是很明显。下面这行实际上创建了带有作用域api1的资源api1

new ApiResource("api1", "My API")

这在文档中很令人困惑,资源和作用域都有相同的名称:api1

当您向下滚动到客户端配置时,使用了作用域(scope)

AllowedScopes = { "api1" }

但在 API 配置 中,它是 资源名称

options.Audience = "api1";

换句话说,范围为api1的资源api1。客户端请求与资源(受众)相关联的范围。令牌中设置了受众以及请求的范围(允许在资源内进行更细粒度的授权,例如实现了多个作用域)。资源通过策略验证是否匹配受众,并通过请求的范围进行过滤。当客户端没有请求任何范围时,规定会要求客户端请求所有已配置的作用域。因此,资源至少需要一个范围。上面的代码展示了如何在内存配置中实现这一点。对于数据库配置,请确保向ApiScopes表添加引用ApiResources表中资源的作用域。

感谢您清晰的解释。您说得对,文档并没有明显表明这一点。 - Tom Troughton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接