Bagikan melalui


Menerapkan keamanan tingkat baris dengan konteks sesi di penyusun API Data

Gunakan fitur konteks sesi SQL untuk menerapkan keamanan tingkat baris di penyusun API Data.

Diagram memperlihatkan bagaimana penyusun Api Data dapat mengatur konteks sesi SQL untuk mengaktifkan keamanan tingkat baris.

Penting

Konteks sesi dengan keamanan tingkat baris SQL Server berbeda dari kebijakan database penyusun API Data. Kebijakan database (misalnya, --policy-database "@item.owner eq @claims.user_id") diterjemahkan ke dalam klausul WHERE oleh penyusun API Data, sementara konteks sesi meneruskan klaim ke SQL Server sehingga keamanan tingkat baris asli SQL menangani pemfilteran.

Prasyarat

  • Server dan database SQL yang ada.
  • CLI penyusun API Data. Menginstal CLI

Nota

Konteks sesi didukung dalam:

  • SQL Server 2016 dan yang lebih baru
  • Azure SQL Database
  • Azure Synapse Analytics (Kumpulan SQL Khusus)
  • Azure Synapse Analytics (kumpulan SQL Tanpa Server) tidak didukung

Membuat tabel dan data SQL

Buat tabel dengan data fiktif untuk digunakan dalam contoh skenario ini.

  1. Sambungkan ke database SQL menggunakan klien atau alat pilihan Anda.

  2. Buat tabel bernama Revenues dengan kolom id, category, revenue, dan accessible_role.

    DROP TABLE IF EXISTS dbo.Revenues;
    
    CREATE TABLE dbo.Revenues(
        id int PRIMARY KEY,  
        category varchar(max) NOT NULL,  
        revenue int,  
        accessible_role varchar(max) NOT NULL  
    );
    GO
    
  3. Sisipkan empat baris sampel ke dalam tabel Revenues.

    INSERT INTO dbo.Revenues VALUES
        (1, 'Book', 5000, 'Oscar'),  
        (2, 'Comics', 10000, 'Oscar'),  
        (3, 'Journals', 20000, 'Hannah'),  
        (4, 'Series', 40000, 'Hannah')
    GO
    

    Dalam contoh ini, accessible_role kolom menyimpan nama peran yang dapat mengakses baris.

Petunjuk / Saran

Kasus penggunaan konteks sesi umum:

  • Pemfilteran berbasis peran (diperlihatkan di sini) menggunakan roles
  • Isolasi multipenyewa menggunakan tenant_id
  • Pemfilteran khusus pengguna menggunakan user_id
  1. Uji data Anda dengan kueri sederhana SELECT * .

    SELECT * FROM dbo.Revenues
    
  2. Buat fungsi bernama RevenuesPredicate. Fungsi ini akan memfilter hasil berdasarkan konteks sesi saat ini.

    CREATE FUNCTION dbo.RevenuesPredicate(@accessible_role varchar(max))
    RETURNS TABLE
    WITH SCHEMABINDING
    AS RETURN SELECT 1 AS fn_securitypredicate_result
    WHERE @accessible_role = CAST(SESSION_CONTEXT(N'roles') AS varchar(max));
    
  3. Buat kebijakan keamanan bernama RevenuesSecurityPolicy menggunakan fungsi .

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

Nota

Klausa WITH SCHEMABINDING diperlukan untuk fungsi yang digunakan dalam kebijakan keamanan sehingga perubahan skema yang mendasarinya tidak membatalkan predikat.

(Opsional) Membuat prosedur tersimpan

Bagian ini menunjukkan pola "hello world" sederhana untuk menggunakan nilai konteks sesi secara langsung di T-SQL.

  1. Buat prosedur tersimpan roles yang membaca nilai konteks sesi dan menggunakannya untuk memfilter hasil.

    CREATE OR ALTER PROCEDURE dbo.GetRevenuesForCurrentRole
    AS
    BEGIN
        SET NOCOUNT ON;
    
        DECLARE @role varchar(max) = CAST(SESSION_CONTEXT(N'roles') AS varchar(max));
    
        SELECT id, category, revenue, accessible_role
        FROM dbo.Revenues
        WHERE accessible_role = @role;
    END
    GO
    

Jalankan alat

Jalankan alat Penyusun API Data (DAB) untuk menghasilkan file konfigurasi dan satu entitas.

  1. Buat konfigurasi baru saat mengatur --set-session-context ke true.

    dab init \
        --database-type mssql \
        --connection-string "<sql-connection-string>" \
        --set-session-context true \
        --auth.provider Simulator
    

    Ketika konteks sesi diaktifkan untuk SQL Server, pembuat API Data mengirimkan klaim pengguna yang diautentikasi ke SQL dengan memanggil sp_set_session_context (misalnya, roles). Mengaktifkan konteks sesi juga menonaktifkan caching respons untuk sumber data tersebut.

Peringatan

Saat set-session-context diaktifkan, cache respons dinonaktifkan untuk sumber data. Untuk skenario lalu lintas tinggi, pertimbangkan untuk menguji performa, mengindeks kolom predikat, atau menggunakan kebijakan database pembangun API Data saat memenuhi kebutuhan Anda.

  1. Tambahkan entitas baru bernama revenue untuk dbo.Revenues tabel.

    dab add revenue \
        --source "dbo.Revenues" \
        --permissions "Authenticated:read"
    
  2. Mulai perangkat pembangun API Data.

    dab start
    
  3. Kueri titik akhir tanpa menentukan peran yang efektif. Amati bahwa tidak ada data yang dikembalikan karena:

    • Peran efektif default ke Authenticated.
    • Tidak ada baris yang memiliki accessible_role = 'Authenticated'.
    • Kebijakan keamanan memfilter hasil saat peran tidak cocok.
    curl http://localhost:5000/api/revenue
    
  4. Kueri titik akhir saat mengatur peran efektif ke Oscar. Perhatikan bahwa hasil yang difilter hanya menyertakan baris Oscar.

    curl -H "X-MS-API-ROLE: Oscar" http://localhost:5000/api/revenue
    
  5. Ulangi menggunakan Hannah role.

    curl -H "X-MS-API-ROLE: Hannah" http://localhost:5000/api/revenue
    

Uji dengan GraphQL

Konteks sesi berfungsi juga dengan kueri GraphQL.

query {
    revenues {
        items {
            id
            category
            revenue
            accessible_role
        }
    }
}

Teruskan header peran:

curl -X POST http://localhost:5000/graphql \
    -H "Content-Type: application/json" \
    -H "X-MS-API-ROLE: Oscar" \
    -d '{"query": "{ revenues { items { id category revenue accessible_role } } }"}'

Apa yang dikirim penyusun API Data ke SQL Server

Saat konteks sesi diaktifkan, penyusun API Data menetapkan nilai konteks sesi pada setiap permintaan sebelum menjalankan kueri Anda.

EXEC sp_set_session_context 'roles', 'Oscar', @read_only = 0;
-- Then executes your query
SELECT * FROM dbo.Revenues;

Semua klaim pengguna yang diautentikasi dikirim sebagai pasangan kunci-nilai. Klaim umum termasuk roles, sub atau oid, dan klaim khusus apa pun dari penyedia identitas Anda.

Uji di SQL

Uji filter dan predikat di SQL secara langsung untuk memastikannya berfungsi.

  1. Sambungkan lagi ke server SQL menggunakan klien atau alat pilihan Anda.

  2. Jalankan sp_set_session_context untuk mengatur klaim konteks roles sesi Anda secara manual ke nilai Oscarstatis .

    EXEC sp_set_session_context 'roles', 'Oscar';
    
  3. Jalankan kueri tipikal SELECT * . Amati bahwa hasilnya secara otomatis difilter menggunakan predikat .

    SELECT * FROM dbo.Revenues;  
    
  4. (Opsional) Kueri tabel menggunakan prosedur tersimpan.

    EXEC dbo.GetRevenuesForCurrentRole;
    

Membersihkan sumber daya

Jika Anda ingin menghapus objek sampel, jalankan:

DROP SECURITY POLICY IF EXISTS dbo.RevenuesSecurityPolicy;
DROP FUNCTION IF EXISTS dbo.RevenuesPredicate;
DROP PROCEDURE IF EXISTS dbo.GetRevenuesForCurrentRole;
DROP TABLE IF EXISTS dbo.Revenues;

Troubleshooting

  • Tidak ada hasil yang dikembalikan: Verifikasi bahwa kebijakan keamanan aktif (SELECT * FROM sys.security_policies), periksa nilai konteks sesi (SELECT SESSION_CONTEXT(N'roles')), dan konfirmasi --set-session-context true diatur dalam konfigurasi penyusun API Data Anda.
  • Semua baris yang dikembalikan: Pastikan kebijakan keamanan tidak dinonaktifkan (WITH STATE = OFF) dan bahwa predikat hanya mengembalikan 1 untuk baris yang diotorisasi.
  • Masalah performa: Indeks kolom predikat (accessible_role), dan pertimbangkan untuk menonaktifkan sementara kebijakan untuk mengisolasi dampak performa.