【问题标题】:IdentityServer 3 returns invalid_clientIdentityServer 3 返回 invalid_client
【发布时间】:2019-05-22 04:50:44
【问题描述】:

我将 IdentityServer3 与 EF 一起使用。我有 API 项目,我想使用 access token 对其访问进行身份验证。 因此,基于sample,我在身份服务器中配置了客户端(用于 API 项目),如下所示

客户端属性

客户端密码 (请注意我输入的任何文本作为秘密值,管理 UI 会自动转换它)

范围

然后使用 POSTMAN 我正在尝试获取访问令牌,但我总是收到 invalid_client 错误

我也尝试过使用 C# 代码获取访问令牌,但得到相同的错误

    static TokenResponse GetClientToken()
    {
        var client = new TokenClient(
            "https://xxxxxxxx/connect/token",
            "A0AD7FB8-2881-484F-xxxxxxxxxxxxxxxxxx",
            "a84iThYxAA5eZpkIzt9xxxxxxxxxxxxxxxxxx");

        return client.RequestClientCredentialsAsync("api").Result;
    }

更新 1
这是我在身份服务器的日志中看到的内容

2018-12-21 19:29:59.284 +00:00 [信息] 开始令牌请求
2018-12-21 19:29:59.301 +00:00 [调试] 开始客户端验证
2018-12-21 19:29:59.302 +00:00 [调试] 开始解析基本身份验证密钥
2018-12-21 19:29:59.302 +00:00 [调试] 开始解析帖子正文中的秘密
2018-12-21 19:29:59.304 +00:00 [调试] 解析器发现秘密:“PostBodySecretParser”
2018-12-21 19:29:59.304 +00:00 [信息] 发现秘密 ID:“A0AD7FB8-2881-484F-ABE0-xxxxxxxx”
2018-12-21 19:29:59.943 +00:00 [调试] 跳过秘密:无描述,秘密不是 SharedSecret 类型。
2018-12-21 19:29:59.943 +00:00 [调试] 未找到匹配的散列密钥。
2018-12-21 19:29:59.943 +00:00 [信息] 秘密验证器无法验证秘密
2018-12-21 19:29:59.944 +00:00 [信息] 客户端验证失败。
2018-12-21 19:29:59.945 +00:00 [信息] 结束令牌请求
2018-12-21 19:29:59.946 +00:00 [信息] 返回错误:invalid_client

更新 2
(秘密值比我之前发布的更新)

【问题讨论】:

  • 发现秘密 ID:“A0AD7FB8-2881-484F-ABE0-xxxxxxxx”。此 Guid 是否旨在成为客户端 ID,而不是秘密?
  • 是的,它的目的是作为客户端 ID,您可以在客户端属性中看到。我附上的屏幕截图
  • 我确认它们是正确的。我认为这与客户秘密的类型有关吗?客户端密码的type 应该是什么?任何字符串?
  • 尝试秘密类型为SharedSecret而不是clientsecret

标签: oauth-2.0 access-token identityserver4 openid-connect identityserver3


【解决方案1】:

尝试使用SharedSecret 而不是clientsecret 的秘密类型。 Identity Server 3 具有以下秘密类型:

  • 共享秘密
  • X509指纹
  • X509 名称
  • X509CertificateBase64

Taken from Identity Server 3 source

此外,您在发送身份验证请求a84iThYxAA5eZpkIzt9xxxxxxxxxxxxxxxxxx 时似乎使用了密码的哈希值,但是,您需要使用用于创建密码的纯文本值。 (58b9....)

【讨论】:

  • @LP13 你能看一下 IdentityServer3 的数据库并检查表 ClientSecrets(或类似的东西),那里存储的秘密类型是什么?您的日志说它不是 SharedSecret 类型。同样在您的 c# 版本中,您使用 a84iThYxAA5eZpkIzt9xxxxxxxxxxxxxxxxxx 作为秘密值,但是,这是秘密的哈希值,您应该使用在添加秘密期间设置的纯文本值。
  • @LP13 好的,看起来不错。现在只需将请求中发送的客户端密码更新为您在创建它时使用的实际值,然后再进行哈希处理。
  • 你是对的,我必须使用我以纯文本输入的秘密值,并且输入应该是SharedSecret。这解决了invalid_client 错误。但现在我得到invalid_scope 错误。日志显示“客户端无法在客户端凭据流中请求 OpenID 范围”
  • 是的,没错。 client_credentials 流无法使用 OpenID 范围,例如 openid email profile,因此请删除它们。这些范围适用于 implicit flowauthorization code 流中存在用户时(还有其他)
  • @LP13 也可以加入聊天室。我可以帮你。 chat.stackoverflow.com/rooms/185631/…
【解决方案2】:

在另一种非常奇怪的情况下,您可能会遇到 invalid_client 错误。

将 IdentityServer3.EntityFramework (IS3.EF) 更新到 2.5.1 似乎会导致客户端密码和作用域密码的默认行为发生变化。在此版本以下,即使您没有为数据库中的机密类型提供值(将其保留为空),Identity Server 也会将其视为“SharedSecret”。它在应用程序级别的类的构造函数中设置它。

但是,较新的 IS.EF3 包包含 AutoMapper 到 5.0 版本的更新。此更新作为副作用似乎停止执行默认构造函数(具有给定配置)。这种方式在数据库中设置客户端密码类型成为事实上的强制性。否则,您会收到 invalid_client 错误,因为机密与其类型不匹配。

看起来作者打算修复此行为更改,但到目前为止该分支尚未合并到 master 中:

ID3.EF - idea_for_setting_defaults_on_entities

请注意,Identity Server 4 已经存在,因此可能永远不会发生合并。

【讨论】:

    猜你喜欢
    • 2017-04-24
    • 2019-08-31
    • 1970-01-01
    • 2018-02-18
    • 2020-05-15
    • 2016-07-10
    • 2018-06-11
    • 2022-06-25
    • 2013-09-07
    相关资源
    最近更新 更多