在数据 API 生成器中使用会话上下文实现行级别安全性

使用 SQL 的 会话上下文 功能在数据 API 生成器中实现行级别安全性。

先决条件

  • 现有的 SQL Server 和数据库。
  • 数据 API 生成器 CLI。 安装 CLI

创建 SQL 表和数据

创建包含虚构数据的表,以在此示例方案中使用。

  1. 使用首选客户端或工具连接到 SQL 数据库。

  2. 创建包含Revenuesidcategoryrevenue列的username表。

    DROP TABLE IF EXISTS dbo.Revenues;
    
    CREATE TABLE dbo.Revenues(
        id int PRIMARY KEY,  
        category varchar(max) NOT NULL,  
        revenue int,  
        username varchar(max) NOT NULL  
    );
    GO
    
  3. 将四个示例书籍行插入Revenues表中。

    INSERT INTO dbo.Revenues VALUES
        (1, 'Book', 5000, 'Oscar'),  
        (2, 'Comics', 10000, 'Oscar'),  
        (3, 'Journals', 20000, 'Hannah'),  
        (4, 'Series', 40000, 'Hannah')
    GO
    
  4. 使用简单的 SELECT * 查询测试数据。

    SELECT * FROM dbo.Revenues
    
  5. 创建一个名为 RevenuesPredicate 的函数。 此函数将基于当前会话上下文筛选结果。

    CREATE FUNCTION dbo.RevenuesPredicate(@username varchar(max))
    RETURNS TABLE
    WITH SCHEMABINDING
    AS RETURN SELECT 1 AS fn_securitypredicate_result
    WHERE @username = CAST(SESSION_CONTEXT(N'name') AS varchar(max));
    
  6. 创建使用函数命名 RevenuesSecurityPolicy 的安全策略。

    CREATE SECURITY POLICY dbo.RevenuesSecurityPolicy
    ADD FILTER PREDICATE dbo.RevenuesPredicate(username)
    ON dbo.Revenues;
    

运行工具

运行数据 API 生成器 (DAB) 工具以生成配置文件和单个实体。

  1. 创建新配置,同时将--set-session-context设置为true。

    dab init \
        --database-type mssql \
        --connection-string "<sql-connection-string>" \
        --set-session-context true
    
  2. 添加一个名为revenue的新实体到表dbo.Revenues中。

    dab add revenue \
        --source "dbo.Revenues" \
        --permissions "anonymous:read"
    
  3. 启动数据 API 生成器工具。

    dab start
    
  4. 导航到 http://localhost:5000/api/revenue 端点。 请注意没有返回任何数据。 发生此行为的原因是未设置会话上下文,并且没有记录与筛选器谓词匹配。

在 SQL 中测试

直接在 SQL 中测试筛选器和谓词,以确保它正常工作。

  1. 使用首选客户端或工具再次连接到 SQL Server。

  2. 通过运行 sp_set_session_context 手动将会话上下文的 name 声明设置为静态值 Oscar

    EXEC sp_set_session_context 'name', 'Oscar';
    
  3. 运行典型 SELECT * 查询。 请注意,结果是通过谓词自动筛选的。

    SELECT * FROM dbo.Revenues;