【问题标题】:Requesting an API resource from Identity Server 4 without scopes从没有范围的 Identity Server 4 请求 API 资源
【发布时间】:2020-03-18 10:14:09
【问题描述】:

我正在尝试使用 Identity Server 4 中的 API 资源,并认为一定有一些我不理解的东西。

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

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

那么,请求提供对无范围 API 资源访问权限的令牌的正确流程是什么?我很确定我在这里遗漏了一些基本知识,我将摆脱这种谦卑和愚蠢的状态。但他们说没有愚蠢的问题,对吧?

【问题讨论】:

    标签: asp.net identityserver4 openid-connect


    【解决方案1】:

    从 4.0.2 开始,也必须定义 ApiScope。我花了几个小时试图弄清楚这一点。因此,例如使用 InMemory 定义 ApiResources、ApiScopes 和客户端。否则,将不会为 api 资源定义范围。

    【讨论】:

    • 我遇到了同样的问题,为什么我必须定义 ApiScopes,当它们已经在 ApiResources 中定义时。我目前看不到定义 ApiResources 而不是仅使用 ApiScopes 的任何好处。也许有人可以在这里提供最佳实践。
    • @MichaelBrunner 我认为资源中的作用域只是将作用域与资源相关联,实际上并没有声明作用域,因此您需要单独声明它们,但这只是我的猜测
    • @GlassCannon 我为自己想出了一些事情:* ApiResources 用于捆绑定义受众的范围 * 为了让我们更容易,为什么使用“丰富的枚举”在代码中定义它们(静态DTO 的只读实例与反射一起查找所有)。这使得不用在任何地方都使用字符串成为可能。
    【解决方案2】:

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

    这也是documented,虽然不是很明显。以下行实际上创建了资源api1,范围为api1

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

    这是文档中令人困惑的部分,资源和作用域具有相同的名称:api1

    当您向下滚动到 client configuration 时,将使用 范围

    AllowedScopes = { "api1" }
    

    但在api configuration 中是资源名称

    options.Audience = "api1";
    

    换句话说,资源api1 范围为api1

    这是如何工作的,客户端请求一个链接到资源(受众)的范围。受众与请求的范围一起设置在令牌中(以允许在资源内进行更细粒度的授权,例如,当实现多个范围时)。该资源验证受众是否匹配,具有按请求范围过滤的策略。当客户端没有请求范围时,根据规范,请求为客户端配置的所有范围。

    因此,资源至少有一个范围是必要的。上面的代码显示了如何为 InMemory 配置执行此操作。对于数据库配置,请确保向 ApiScopes 表添加一个范围,该范围引用 ApiResources 表中的资源。

    【讨论】:

    • 感谢您的清晰解释。你是对的,文档并没有说明这一点。
    猜你喜欢
    • 1970-01-01
    • 2021-03-06
    • 2018-10-17
    • 2020-01-06
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 2018-12-10
    • 2020-02-06
    相关资源
    最近更新 更多