您应该使用客户端凭据授权类型进行身份验证 server-to-server 吗?

Should you use Client Credentials Grant Type with authenticating server-to-server?

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

我正在使用 AWS Cognito,并且基于此 post 的 "Client credentials grant" 部分进行身份验证。

我现在的流量是:

  1. 客户注册我的 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. 客户端从 AWS
  2. 以 jwt 的形式接收 access_token
  3. 客户端发送 access_token 授权 header 到我的 Api
  4. 我的 Api 验证 access_token 有效
  5. 我的 Api 提供适用范围内的资源访问权限,client_id

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

如果是这样,有人可以告诉我每个应用程序客户端的定价是多少吗?是在 page 的 "Users who sign in directly with their User Pool credentials or with social identity providers:" 部分吗?

想了想,这就是我要做的(前言:这绝对不是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 table.

// 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 table(即,不授予对任何角色的访问权限)并创建一个 SECURITY DEFINER 函数,该函数采用 user_idprivate_key 作为输入,检查该行是否存在于您的 api_keys table 和 returns 中,无论您需要从 secret_stuffs table .

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

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

Authorization: Basic BASE64(CLIENT_ID:CLIENT_SECRET)