使用 IAM 身份验证管理用户

本页面介绍如何将使用 IAM 数据库身份验证的用户或服务帐号添加到数据库,以及如何管理这些用户和服务帐号。如需详细了解 IAM 集成,请参阅 IAM 数据库身份验证概览

准备工作

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  4. 安装并初始化 Cloud SDK
  5. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  6. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  7. 安装并初始化 Cloud SDK
  8. 启用 Cloud Key Management Service API。

    启用 API

  9. 确保您的用户帐号具有 Cloud SQL Admin 角色。

    转到 IAM 页面

  10. 在 Cloud SQL 实例上启用 IAM 数据库身份验证
  11. 对于包含用户需要访问的数据库的每个项目,请确保向需要该权限的用户授予 IAM 访问权限。请参阅授予、更改和撤消对资源的访问权限
  12. 确保您已为需要访问项目中的数据库的每个服务添加了服务帐号

将 IAM 用户或服务帐号添加到数据库

对于您要有权访问数据库实例的每位 IAM 用户,您都必须为其创建一个新的数据库用户。数据库用户名必须是 IAM 用户的电子邮件地址,例如 test-user@gmail.com

使用 REST 命令时,用户名必须使用英文引号,因为它包含特殊字符(@.)。

服务帐号使用 service-account-name@project-id.iam.gserviceaccount.com 格式。

如需添加 IAM 用户或服务帐号,您需要添加新的数据库用户并选择 IAM 作为身份验证方法:

控制台

  1. 在 Google Cloud Console 中,转到 Cloud SQL 实例页面。

    转到“Cloud SQL 实例”

  2. 点击实例名称,打开其概览页面。
  3. 从 SQL 导航菜单中选择用户
  4. 点击添加用户帐号。系统会打开将用户帐号添加到实例 instance_name 标签页。
  5. 点击 Cloud IAM 单选按钮。
  6. 成员字段中添加要添加的用户或服务帐号的电子邮件地址。
  7. 点击添加。该用户现在位于用户列表中。
  8. 如需授予用户登录权限,请点击 三角形 并选择添加 IAM 角色。此操作会将 Cloud SQL Instance User 角色分配给用户。

gcloud

创建用户帐号

使用电子邮件地址(如 test-user@gmail.com)来标识用户。

替换以下内容:

  • USERNAME:用户的电子邮件地址。
  • INSTANCE_NAME:您要向用户授予访问权限的实例的名称。
gcloud sql users create USERNAME \
--instance=INSTANCE_NAME \
--type=cloud_iam_user

创建服务帐号

替换以下内容:

  • SERVICE_ACCT:服务帐号的电子邮件地址。
  • INSTANCE_NAME:您要向服务帐号授予访问权限的实例的名称。
gcloud sql users create SERVICE_ACCT \
--instance=INSTANCE_NAME \
--type=cloud_iam_service_account

REST v1

创建用户帐号

在使用任何请求数据之前,请先进行以下替换:

  • project-id:您的项目 ID
  • instance-id:您要向其添加用户的实例的 ID
  • username:用户的电子邮件地址
  • operation-id:操作的 ID

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/users

请求 JSON 正文:

{
  "name": "username",
  "type": "CLOUD_IAM_USER"
  }

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:44:16.656Z",
  "startTime": "2020-02-07T22:44:16.686Z",
  "endTime": "2020-02-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

创建服务帐号

在使用任何请求数据之前,请先进行以下替换:

  • service-acct:您的服务帐号电子邮件地址
  • project-id:您的项目 ID
  • instance-id:您要向其添加服务帐号的实例的 ID
  • operation-id:操作的 ID

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id/users

请求 JSON 正文:

{
    "name": "service-acct"
    "type": "CLOUD_IAM_SERVICE_ACCOUNT"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
"kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-11-20T04:08:00.211Z",
  "startTime": "2020-11-20T04:08:00.240Z",
  "endTime": "2020-11-20T04:08:02.003Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

REST v1beta4

创建用户帐号

在使用任何请求数据之前,请先进行以下替换:

  • project-id:您的项目 ID
  • instance-id:您要向其添加用户的实例的 ID
  • username:用户的电子邮件地址
  • operation-id:操作的 ID

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users

请求 JSON 正文:

{
  "name": "username",
  "type": "CLOUD_IAM_USER"
  }

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-02-07T22:44:16.656Z",
  "startTime": "2020-02-07T22:44:16.686Z",
  "endTime": "2020-02-07T22:44:20.437Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

创建服务帐号

在使用任何请求数据之前,请先进行以下替换:

  • service-acct:您的服务帐号电子邮件地址
  • project-id:您的项目 ID
  • instance-id:您要向其添加服务帐号的实例的 ID
  • operation-id:操作的 ID

HTTP 方法和网址:

POST https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users

请求 JSON 正文:

{
    "name": "service-acct"
    "type": "CLOUD_IAM_SERVICE_ACCOUNT"
}

如需发送您的请求,请展开以下选项之一:

您应该收到类似以下内容的 JSON 响应:

{
"kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id",
  "status": "DONE",
  "user": "user@example.com",
  "insertTime": "2020-11-20T04:08:00.211Z",
  "startTime": "2020-11-20T04:08:00.240Z",
  "endTime": "2020-11-20T04:08:02.003Z",
  "operationType": "CREATE_USER",
  "name": "operation-id",
  "targetId": "instance-id",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id",
  "targetProject": "project-id"
}

向用户或服务帐号添加 IAM 政策绑定

在给定项目 ID 和绑定的情况下,此过程将政策绑定添加到特定项目的 IAM 政策。绑定命令由成员、角色和可选条件组成。如需大致了解 IAM 数据库身份验证的 IAM 政策绑定,请参阅内置身份验证与 IAM 身份验证(IAM 数据库身份验证)之间的差异

数据库用户名必须是 IAM 用户的电子邮件地址,例如 test-user@gmail.com。它必须使用英文引号,因为它包含特殊字符(@.)。

控制台

  1. 在 Google Cloud Console 中,转到 IAM 页面。

    转到 IAM

  2. 点击添加
  3. 新成员中,输入电子邮件地址。您可以将个人或服务帐号添加为成员,但每个项目必须至少有一名个人成员。
  4. 角色中,导航到 Cloud SQL,然后选择 Cloud SQL Instance UserCloud SQL Client
  5. 点击保存

gcloud

运行带有 --role=roles/cloudsql.instanceUser 标志的 gcloud projects add-iam-policy-binding

向用户帐号添加政策绑定

替换以下内容:

  • PROJECT_ID:您要授权用户使用的项目的 ID。
  • USERNAME:用户或服务帐号的电子邮件地址。
  gcloud projects add-iam-policy-binding PROJECT_ID \
  --member=user:USERNAME \
  --role=roles/cloudsql.instanceUser
  

使用 --role=roles/cloudsql.client 标志再次运行 gcloud projects add-iam-policy-binding

向服务帐号添加政策绑定

替换以下内容:

  • PROJECT_ID:您要授权用户使用的项目的 ID。
  • SERVICE_ACCT:用户或服务帐号的电子邮件地址。
  gcloud projects add-iam-policy-binding PROJECT_ID \
  --member=serviceAccount:SERVICE_ACCT --role=roles/cloudsql.instanceUser
  

使用 --role=roles/cloudsql.client 标志再次运行 gcloud projects add-iam-policy-binding

REST

通过修改 get-iam-policy 命令返回的 JSON 或 YAML 绑定政策,将 cloudsql.instanceUsercloudsql.client 角色授予两种类型的帐号。请注意,此政策更改在设置更新后的政策后才会生效。

    {
      "role": "roles/cloudsql.instanceUser",
      "members": [
                   "user:user@example.com"
                   "serviceAccount:service1@sql.iam.gserviceaccount.com"
      ]
    }
    {
      "role": "roles/cloudsql.client",
      "members": [
                   "user:user@example.com"
                   "serviceAccount:service1@sql.iam.gserviceaccount.com"
      ]
    }

向 IAM 用户授予数据库权限

默认情况下,将 IAM 用户添加到数据库实例时,该新用户不会对任何数据库授予权限。

要授予用户登录访问权限或其他权限,请使用 GRANT 语句。如需查看您可以向用户和服务帐号授予的完整权限列表,请参阅 GRANT 参考页面。通过 mysql 命令行运行 GRANT。

替换以下内容:

  • USERNAME:对于用户帐号,这是 IAM 用户的电子邮件地址,@ 和网域字符串均被截断。例如,如果 IAM 用户的电子邮件地址为 test-user@gmail.com,则用户名为 test-user。对于服务帐号,这是不带 @project-id.iam.gserviceaccount.com 域名的服务帐号的电子邮件地址。
  • TABLE_NAME:您要向用户授予访问权限的表的名称。
    grant select on TABLE_NAME to "USERNAME";
    
  • 从数据库中移除 IAM 用户或服务帐号

    要从数据库中移除用户或服务帐号,请从实例中删除该帐号:

    控制台

    1. 在 Google Cloud Console 中,转到 Cloud SQL 实例页面。

      转到“Cloud SQL 实例”

    2. 点击实例名称,打开其概览页面。
    3. 从 SQL 导航菜单中选择用户
    4. 针对您要移除的用户,点击
    5. 选择移除。这样只会撤消对此实例的访问权限。

    gcloud

    撤消用户

    使用电子邮件地址(如 test-user@gmail.com)来标识用户。

    替换以下内容:

    • USERNAME:不带 @域名的电子邮件地址。
    • INSTANCE_NAME:您要从中移除用户的实例的名称。
    gcloud sql users delete USERNAME \
    --instance=INSTANCE_NAME
    

    删除服务帐号

    替换以下内容:

    • SERVICE_ACCT:服务帐号的电子邮件地址。
    • INSTANCE_NAME:您要从中移除用户的实例的名称。
    gcloud sql users delete SERVICE_ACCT \
    --instance=INSTANCE_NAME
    

    REST v1beta4

    以下请求使用 users:delete 方法删除指定的用户帐号。

    在使用任何请求数据之前,请先进行以下替换:

    • project-id:您的项目 ID
    • instance-id:所需的实例 ID
    • username:用户或服务帐号的电子邮件地址

    HTTP 方法和网址:

    DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id/users?host=&name=username

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

    {
      "kind": "sql#operation",
      "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/instances/instance-id",
      "status": "DONE",
      "user": "user@example.com",
      "insertTime": "2020-02-07T22:38:41.217Z",
      "startTime": "2020-02-07T22:38:41.217Z",
      "endTime": "2020-02-07T22:38:44.801Z",
      "operationType": "DELETE_USER",
      "name": "operation-id",
      "targetId": "instance-id",
      "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/project-id/operations/operation-id",
      "targetProject": "project-id"
    }
    

    在审核日志中查看登录信息

    您可以启用审核日志以捕获对数据库的 IAM 登录。如果出现登录问题,您可以使用审核日志来诊断问题。

    注意:Audit Logging 会产生额外费用。如需了解详情,请参阅日志记录数据的价格

    配置后,您可以使用日志查看器查看成功登录的数据访问审核日志

    例如,日志可能包含类似如下所示的信息:

    {
     insertId: "..."
     logName: "projects/.../logs/cloudaudit.googleapis.com%2Fdata_access"
     protoPayload: {
      @type: "type.googleapis.com/google.cloud.audit.AuditLog"
      authenticationInfo: {
       principalEmail: "..."
      }
      authorizationInfo: [
       0: {
        granted: true
        permission: "cloudsql.instances.login"
        resource: "instances/..."
        resourceAttributes: {
        }
       }
      ]
      methodName: "cloudsql.instances.login"
      request: {
       @type: "type.googleapis.com/google.cloud.sql.authorization.v1.InstancesLoginRequest"
       clientIpAddress: "..."
       database: "..."
       databaseSessionId: ...
       instance: "projects/.../locations/us-central1/instances/..."
       user: "..."
      }
      requestMetadata: {
       callerIp: "..."
       destinationAttributes: {
       }
       requestAttributes: {
        auth: {
        }
        time: "..."
       }
      }
      resourceName: "instances/..."
      serviceName: "cloudsql.googleapis.com"
      status: {
      }
     }
     receiveTimestamp: "..."
     resource: {
      labels: {
       database_id: "...:..."
       project_id: "..."
       region: "us-central"
      }
      type: "cloudsql_database"
     }
     severity: "INFO"
     timestamp: "..."
    }
    

    排查登录失败问题

    尝试登录失败时,出于安全考虑,MySQL 会返回最少的错误消息。例如:

    $MYSQL_PWD=`gcloud-access-token mysql` --enable-cleartext-plugin --ssl-ca=server-ca.pem
    --ssl-cert=client-cert.pem --ssl-key=client-key.pem   --host=ip_address --user=testuser
    Access denied for user 'testuser'@'...' (using password: NO)
    

    您可以查看 MySQL 错误日志以详细了解错误。如需了解详情,请参阅查看日志

    例如,对于前面的错误,以下日志条目说明了您可以执行来解决该问题的操作。

    F ... [152172]: [1-1] db=...,user=... FATAL:  Cloud SQL IAM user authentication failed for user "..."
    I ... [152172]: [2-1] db=...,user=... DETAIL:  Request is missing required authentication credential. Expected OAuth 2 access token, log in cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
    

    检查您收到的错误消息。如果消息未指明您使用的是“Cloud SQL IAM 用户身份验证”还是“Cloud SQL IAM 服务帐号身份验证”,请验证用于登录的数据库用户类型是 CLOUD_IAM_USERCLOUD_IAM_SERVICE_ACCOUNT。对于 IAM 用户,验证数据库用户名是否为 IAM 用户的电子邮件地址(不包含 @ 和网域)。对于服务帐号,验证它是否为服务帐号的电子邮件地址(不带 @project-id.iam.gserviceaccount.com)。

    如果您使用的是 IAM 数据库身份验证,请查看错误消息的详细信息。您可以在数据库错误日志中找到错误消息。如果消息指明您发送用作密码的访问令牌 (OAuth 2.0) 无效,您可以使用 gcloud auth application-default print-access-token gcloud 命令查找令牌的详细信息,如下所示:

    curl -H "Content-Type: application/x-www-form-urlencoded" \
    -d "access_token=$(gcloud auth application-default print-access-token)" \
    https://www.googleapis.com/oauth2/v1/tokeninfo
    

    验证该令牌适用于预期的 IAM 用户或服务帐号,并且未过期。

    如果详细信息指明缺少权限,请验证已使用预定义的 Cloud SQL Instance User 角色或实例项目的 IAM 政策中的自定义角色为 IAM 用户或服务帐号授予了 cloudsql.instances.login 权限。如需其他帮助,请使用 IAM 政策问题排查工具

    如果由于 IAM 数据库身份验证不可用而导致登录失败,则用户可以使用默认的 MySQL 用户名和密码登录。这种登录方法仍可为用户提供整个数据库的访问权限。验证连接是否为安全连接。

    后续步骤