【问题标题】:Should you use Client Credentials Grant Type with authenticating server-to-server?您是否应该将客户端凭据授予类型与服务器到服务器的身份验证一起使用?
【发布时间】:2020-03-12 18:03:21
【问题描述】:

我正在创建一个 api 服务(“My Api”),最终用户是其他 api(“客户端”)。这是我的第一个客户端不是真人的应用程序,所以我想确保我正确地通过了身份验证流程。

我正在使用 AWS Cognito,并且基于此 post 的“客户端凭证授予”部分的身份验证流程。

我现在的流程是:

  1. 客户端注册 My Api
  2. 我的 Api 在 AWS 上创建了一个应用程序客户端。我有一个简单的仪表板,它将向客户端显示 client_id 和 client_secret(我的 Api 公开了一个端点来旋转 client_secrets)
  3. 客户端将以下 POST 发送到我的 AWS oauth2 域
curl -X POST \
  https://[DOMAIN_NAME].auth.[REGION].amazoncognito.com/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'authorization: Basic BASE64(client_id:client_secret)' \
  -d 'grant_type=client_credentials&scope=[SCOPE]'
  1. 客户端以 jwt 的形式从 AWS 接收 access_token
  2. 客户端将授权标头中的 access_token 发送到 My Api
  3. 我的 Api 验证 access_token 是否有效
  4. My Api 提供对适用范围和 client_id 的资源的访问权限

我必须在 AWS Cognito 上为每个客户端创建一个应用程序客户端,这似乎很奇怪。当您使用客户端凭据而不是授权代码进行身份验证时,这是否正常?

如果是这样,有人可以告诉我每个应用客户端的定价是多少吗?是否在此page 的“直接使用其用户池凭据或社交身份提供者登录的用户:”部分中?

【问题讨论】:

  • 我也在尝试了解使用客户端凭据授予类型的定价。你有没有到任何地方?没有用户,因此该链接页面上的数字并不真正适用。
  • 我也是来问这个的。我仍然不明白为什么这是 Cognito 能做到的最好的。为每个“机器对机器”实例创建一个 App Client 是没有意义的。还考虑到每个用户池有 1000 个应用程序客户端的软限制。而且由于凭证流将提供一个最长有效期为 1 天的 JWT 令牌,这意味着另一台“机器”需要每 24 小时刷新一次令牌,这有点糟糕。最后,我提供的 access_key 没有指向我池中用户的链接。所以我不可能知道谁在和我的 API 说话。好东西 AWS!

标签: amazon-web-services authentication oauth-2.0 amazon-cognito access-token


【解决方案1】:

几个月前,当我们必须对来自服务器端应用程序的请求进行身份验证时,我遇到了同样的挑战。根据我的研究,隐式流和授权码流适用于前端登录身份验证,客户端凭据流适用于机器对机器。我还设置了一个单独的数据库来映射我们计划进行身份验证的每个服务器端应用程序的客户端应用程序 ID。

我在如何使用 OAuth 2.0 客户端凭据流中找到了这个 tutorial。详细讨论了如何在邮递员中进行测试的示例。

Authorization: Basic BASE64(CLIENT_ID:CLIENT_SECRET)

【讨论】:

  • 想澄清一下,客户端凭据流是针对公司间机器到机器的。
【解决方案2】:

经过一段时间的思考,这就是我要做的(前言:这绝对不是 AWS/Banking 级别的身份验证)。下面的代码在 postgres 中。

我会设计数据库架构以容纳多个租户see this paper by Google for ideas。每个用户(例如,组织的员工)都有一个 Cognito 用户,该用户将链接到该用户。

CREATE TABLE organizations (
  org_id uuid
);

CREATE TABLE users (
  user_id      uuid,
  cognito_uid  uuid,
  org_id       uuid REFERENCES organizations(org_id)
);

CREATE TABLE secret_stuffs (
  secrets   varchar
);

然后我会创建一个 api_keys 表。

// We only want user to have two keys max
CREATE TYPE api_key_type AS ENUM (
  'primary',
  'secondary'
);

CREATE TABLE api_keys (
  PRIMARY KEY (
    user_id,
    key_type
  )

  org_id       uuid REFERENCES organizations(org_id),
  user_id      uuid REFERENCES users(user_id),
  key_type     api_key_type,
  private_key  varchar
);

// You'd probably want to create a composite index with user_id and private_key fields since we'll create a function that access both

我将锁定api_keyssecret_stuffs 表(即,不授予对任何角色的访问权限)并创建一个SECURITY DEFINER 函数,该函数将user_idprivate_key 作为输入,检查该行存在于您的 api_keys 表中,并从 secret_stuffs 表中返回您需要的任何内容。

【讨论】:

    猜你喜欢
    • 2018-11-26
    • 2012-08-28
    • 1970-01-01
    • 2017-08-15
    • 2013-03-17
    • 1970-01-01
    • 2019-01-18
    • 2019-05-16
    • 2013-06-18
    相关资源
    最近更新 更多