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

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

本教程介绍了如何在 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. 输入实例名称,然后点击删除 ,以确认您要删除该实例。

后续步骤

  • 了解 参数化安全视图

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