【问题标题】:invalid_scope error in access token for client credential flow客户端凭据流的访问令牌中的 invalid_scope 错误
【发布时间】:2017-10-26 04:31:32
【问题描述】:

我在客户端凭据流的访问令牌请求中收到 invalid_scope 错误。错误日志指出“无法在客户端凭据流中请求 OpenID 范围”。我没有要求开放 id 范围。我不知道它是从哪里来的。我需要使用客户端凭据流生成访问令牌。

问题/重现问题的步骤

API 资源定义。

public IEnumerable GetApiResources()
{
    return new List {
        new ApiResource
        {
            Name = "WidgetApi",
            DisplayName = "Widget Management API",
            Description = "Widget Management API Resource Access",
            ApiSecrets = new List { new Secret("scopeSecret".Sha256()) },
            Scopes = new List {
                new Scope("WidgetApi.Read"),
                new Scope("WidgetApi.Write")
            }
        }
     };
}

客户定义;

return new List
{
    new Client
    {
        ClientId = "WidgetApi Client Id",
        ClientName = "WidgetApi Client credential",
        RequireConsent = false,
        AllowedGrantTypes = GrantTypes.ClientCredentials,
        ClientSecrets =
        {
            new Secret( clientSecret.Sha256())
        },
       // scopes that client has access to
       AllowedScopes = { "WidgetApi.Read", "WidgetApi.Write"},
       AccessTokenLifetime = 3600
   };
}

使用邮递员访问令牌请求正文(键-值)

grant_type  client_credentials
response_type  id_token
scope  WidgetApi.Read WidgetApi.Write
client_secret  xxxxxxxxxxxxxxxxxxxxxx
client_id  WidgetApiClientId

日志文件的相关部分

dbug: Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerConnection[4]
Closing connection to database 'IdentityServer4Db' on server 'localhost\SQLEXPRESS'.
dbug: IdentityServer4.EntityFramework.Stores.ResourceStore[0]
Found PssUserMgtApi.Read, PssUserMgtApi.Write API scopes in database
fail: IdentityServer4.Validation.TokenRequestValidator[0]
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx cannot request OpenID scopes in client credentials flow
fail: IdentityServer4.Validation.TokenRequestValidator[0]

{
        "ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "ClientName": "xxxxxxxxxxxxxxxxxxxxxxxxx",
        "GrantType": "client_credentials",
        "Scopes": "xxxxxxxxxx.Read xxxxxxxxxxxxx.Write",
        "Raw": {
            "grant_type": "client_credentials",
            "response_type": "id_token",
            "scope": "xxxxxxxxxxxx.Read xxxxxxxxxxxxx.Write",
            "client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
 }

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 5292.2873ms 400 application/json
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HL51IVGKG792" completed keep alive response.

【问题讨论】:

  • 看起来您的 client_id 是“WidgetApi Client Id”,但在邮递员中您有“WidgetApiClientId”...
  • @MiguelDomingues 这应该会导致 Invalid Client 错误。
  • 您注册WidgetApi.ReadWidgetApi.Write 是否为IdentityResource 而不是ApiResource?您仍然会收到一个错误,要求为 client_credentials 流输入 id_token。你应该要求“令牌”。

标签: oauth-2.0 access-token identityserver4


【解决方案1】:

由于在客户端凭据流中没有标记用户,通常情况下,客户端凭据不打算标记范围,并且许多框架不支持它。

https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/ 说:

范围(可选): 您的服务可以支持客户端凭据授予的不同范围。 实际上,实际上支持这一点的服务并不多。

【讨论】:

    【解决方案2】:

    如果您遇到此问题,只需在 ClientScopes 的数据库中删除给定客户端的“openid”范围。

    【讨论】:

      【解决方案3】:

      检查您的客户凭据详细信息是否正确。您还可以找到这个简单的分步说明来使用此link 配置客户端凭据流

      【讨论】:

        【解决方案4】:

        其实问题已经包含答案了:

        grant_type client_credentials
        response_type id_token
        范围 WidgetApi.Read WidgetApi.Write
        client_secret xxxxxxxxxxxxxxxxxxxxxx
        client_id WidgetApiClientId

        client_credentials 类型的请求应该在token 端点处理,并且不能要求id_token,因为流程是非交互式的。冗余参数正在中断流程。

        【讨论】:

          【解决方案5】:

          IdentityServer4 2.1.3 出现此错误,但 IdentityServer4 2.3.2 没有。从项目的 GitHub 问题看来,它已在 2.3 中修复:

          https://github.com/IdentityServer/IdentityServer4/issues/2295#issuecomment-405164127

          【讨论】: