安全地访问和控制应用数据

参数化安全视图可为应用提供数据安全和行级访问权限控制。它们会根据应用用户的身份过滤查询结果。

本教程介绍了如何在 Cloud SQL 中设置参数化安全视图,配置数据库角色和权限以限制对基表的访问权限,以及验证数据安全。本文档中提供的示例仅用于演示目的。

什么是参数化安全视图?

作为一般最佳实践,您的应用应使用对数据库具有最低必需访问权限的服务帐号运行。例如,如果您的应用不应写入数据库,则应使用具有只读访问权限的角色。您应在数据库级层配置这些访问权限控制。

当您的应用需要比标准数据库级层访问权限更精细的安全措施时,您可以使用参数化安全视图来确保用户只能查看其授权的数据。参数化安全视图提供动态数据安全和行级访问权限控制,适用于多租户 SaaS 应用,而无需为每个应用最终用户提供单独的数据库角色。

使用参数化安全视图具有三个主要优势:

  • 动态数据安全和行级访问权限控制:使用最终用户标识符过滤查询,以便用户只能访问其授权的数据,无论查询措辞如何。
  • 更轻松的角色管理:为所有应用用户使用单个共享数据库角色,而不是为每个用户管理单独的数据库角色。

目标

  • 使用指定视图参数创建参数化安全视图。
  • 创建供应用用于连接到数据库和访问参数化安全视图的数据库角色。
  • 向新角色授予对参数化安全视图的权限,并撤消对基表的访问权限。
  • 使用新角色进行连接,并验证是否无法访问受限表。
  • 使用 mysql.execute_parameterized_query 存储过程或使用 QueryData API 对参数化视图运行查询。

费用

在本文档中,您将使用的以下收费组件: Google Cloud

您可使用价格计算器根据您的预计使用量来估算费用。

新 Google Cloud 用户可能有资格申请免费试用。

为避免继续计费,请在完成本文档中的任务后删除您创建的资源。如需了解详情,请参阅清理。

准备工作

在创建参数化安全视图之前,请完成以下前提条件。

启用结算功能及所需 API

  1. 在 Google Cloud 控制台中,选择一个项目。

    转到“项目选择器”

  2. 确保您的 Google Cloud 项目已启用结算功能。

  3. 启用创建和连接到 Cloud SQL 所需的 Cloud API。

    1. 启用该 API

    2. 在确认项目步骤中,点击下一步以确认您要更改的项目的名称。

    3. 在启用 API 步骤中,点击启用 以启用以下内容:

      • Cloud SQL for MySQL API
      • Knowledge Catalog API

创建并连接到数据库

  1. 创建实例。
  2. 连接到您的实例并创建数据库。

准备环境

为了准备对参数化安全视图运行查询,请设置数据库、数据库角色和应用架构。

启用数据库标志

  • 确保您的 Cloud SQL for MySQL 实例运行的是 Cloud SQL for MySQL 8.0.43 或更高版本。如果您的 Cloud SQL for MySQL 8.0 实例运行的是较低的次要版本,则可以执行次要版本升级。
  • 为您的实例启用 cloudsql_parameterized_secure_view 数据库标志。此标志更改不需要重启数据库。如需了解详情,请参阅配置实例的数据库标志。

设置数据库和角色

  1. 在 Google Cloud 控制台中,前往 Cloud SQL 页面。

    转到 Cloud SQL

  2. 从列表中选择一个实例。

  3. 在导航菜单中,点击 Cloud SQL Studio 。

  4. 使用管理员用户账号登录 Studio 。

  5. 点击身份验证 。探索器窗格会显示数据库中的对象列表。

  6. 点击新的 SQL 编辑器标签页 或新标签页 以打开新标签页。

  7. 为应用数据和视图创建一个名为 store_db 的数据库:

    CREATE DATABASE IF NOT EXISTS store_db;
    USE store_db;
    
  8. 创建一个新的数据库角色,用于针对参数化视图运行查询。应用使用此角色连接到数据库并运行查询,访问权限严格限制为授权视图:

    CREATE ROLE 'psv_user';
    

创建表并插入数据

  1. 在 Google Cloud 控制台中,前往 Cloud SQL 页面。

    转到 Cloud SQL

  2. 从列表中选择一个 Cloud SQL for MySQL 实例。

  3. 在导航菜单中,点击 Cloud SQL Studio 。

  4. 使用数据库身份验证登录 Studio 。

  5. 点击新标签页 以打开新的 SQL 编辑器标签页。

  6. 创建表并插入数据:

    CREATE TABLE store_db.checked_items (
    bag_id INT,
    timestamp TIMESTAMP,
    loc_code CHAR(3),
    scan_type CHAR(1),
    location TEXT,
    customer_id INT
    );
    
    INSERT INTO store_db.checked_items (bag_id, timestamp, loc_code, scan_type, location, customer_id) VALUES
    (101, '2023-10-26 10:00:00', 'ABC', 'I', 'Warehouse A', 123),
    (102, '2023-10-26 10:15:30', 'DEF', 'O', 'Loading Dock B', 456),
    (103, '2023-10-26 10:30:45', 'GHI', 'I', 'Conveyor Belt 1', 789),
    (104, '2023-10-26 11:00:00', 'JKL', 'O', 'Shipping Area C', 101),
    (105, '2023-10-26 11:45:15', 'MNO', 'I', 'Sorting Station D', 202),
    (106, '2023-10-26 12:00:00', 'PQR', 'O', 'Truck Bay E', 303);
    

创建参数化安全视图并设置访问权限

如需创建参数化安全视图,请按以下步骤操作:

  1. 在 Google Cloud 控制台中,前往 Cloud SQL 页面。

    转到 Cloud SQL

  2. 从列表中选择一个实例。

  3. 在导航菜单中,点击 Cloud SQL Studio 。

  4. 登录 Studio 并以您在上一部分中使用的 store_db 用户账号连接到 database。

  5. 点击身份验证 。探索器窗格会显示数据库中的对象列表。

  6. 点击新的 SQL 编辑器标签页 或新标签页 以打开新标签页。

  7. 如需提供对视图的有限访问权限,请创建参数化视图:

    CREATE VIEW store_db.secure_checked_items AS
    SELECT bag_id, timestamp, location
    FROM store_db.checked_items t
    WHERE customer_id = @app_end_userid;
    
  8. 向 psv_user 角色授予对参数化视图的 SELECT 访问权限:

    GRANT SELECT ON store_db.secure_checked_items TO 'psv_user';
    
  9. 授予对用于安全执行参数化查询的内置系统存储过程的执行权限:

    GRANT EXECUTE ON PROCEDURE mysql.execute_parameterized_query TO 'psv_user';
    
  10. 可选。从 psv_user 中显式撤消对基表的任何直接权限,以确保用户无法绕过安全视图:

    REVOKE ALL PRIVILEGES ON store_db.checked_items FROM 'psv_user';
    
  11. 向经过 IAM 身份验证的数据库用户或应用登录账号授予 psv_user 角色:

    GRANT 'psv_user' TO 'IAM_USER_EMAIL'@'%';
    
    SET DEFAULT ROLE 'psv_user' TO 'IAM_USER_EMAIL'@'%';
    

    将 IAM_USER_EMAIL 替换为您的 IAM 用户电子邮件地址或应用登录账号。

验证数据安全

如需验证您是否可以查询参数化安全视图,请按以下步骤操作:

  1. 使用受限 IAM 电子邮件地址或应用登录信息登录 Cloud SQL Studio 。

  2. 点击新标签页 以打开新的 SQL 编辑器标签页。

  3. 查询基表并验证访问权限是否被拒绝。

    SELECT * FROM store_db.checked_items;
    

    数据库返回 ERROR 1142 (42000): SELECT command denied to user 'IAM_USER_EMAIL'@'%' for table 'checked_items' 错误。

  4. 使用内置 mysql.execute_parameterized_query 存储过程查询参数化安全视图。

    CALL mysql.execute_parameterized_query(
      'SELECT * FROM store_db.secure_checked_items',
      'app_end_userid=303'
    );
    
  5. 使用 SQL 语法和带有 PSV 参数的 QueryData 请求查询参数化安全视图。

     curl -X POST \
       "https://geminidataanalytics.googleapis.com/v1beta/projects/PROJECT_ID/locations/REGION:queryData" \
       -H "Authorization: Bearer $(gcloud auth print-access-token)" \
       -H "Content-Type: application/json; charset=utf-8" \
       -d '{
         "prompt": "Show me the checked items.",
         "context": {
           "datasource_references": {
             "cloud_sql_reference": {
               "database_reference": {
                 "engine": "MYSQL",
                 "project_id": "PROJECT_ID",
                 "region": "REGION",
                 "instance_id": "INSTANCE_ID",
                 "database_id": "DATABASE_ID"
               }
             }
           },
           "parameterized_secure_view_parameters": {
             "parameters": {
               "key": "app_end_userid"
               "app_end_userid": "303"
             }
           }
         },
         "generation_options": {
           "generate_query_result": true,
           "generate_natural_language_answer": true,
           "generate_explanation": true
         }
       }'

    替换以下值:

    • PROJECT_ID:您的 Google Cloud 项目 ID。
    • REGION:Cloud SQL for MySQL 实例所在的区域。
    • INSTANCE_ID:Cloud SQL for MySQL 实例的 ID。
    • DATABASE_ID:Cloud SQL for MySQL 数据库的 ID。

清理

删除集群

删除您在准备工作部分中创建的集群时,您创建的所有对象也会删除。

  1. 在 Google Cloud 控制台中,前往 Cloud SQL 页面。

    转到 Cloud SQL

  2. 从列表中选择一个实例。

  3. 点击删除 。

  4. 输入实例名称,然后点击删除 ,以确认您要删除该实例。

后续步骤

  • 了解 参数化安全视图。

  • 了解如何 使用参数化安全视图。