Dela via


Implementera säkerhet på radnivå med sessionskontext i Data API Builder

Använd sessionskontextfunktionen i SQL för att implementera säkerhet på radnivå i Data API Builder.

Diagram som visar hur Data API Builder kan ange SQL-sessionskontext för att aktivera säkerhet på radnivå.

Viktigt!

Sessionskontext med säkerhet på radnivå i SQL Server skiljer sig från databasprinciper för Data API Builder. Databasprinciper (till exempel --policy-database "@item.owner eq @claims.user_id") översätts till WHERE-satser av Data API Builder, medan sessionskontext vidarebefordrar anspråk till SQL Server så att SQL-inbyggd säkerhet på radnivå hanterar filtreringen.

Förutsättningar

  • Befintlig SQL-server och databas.
  • Data-API-byggarens CLI. Installera CLI

Anmärkning

Sessionskontext stöds i:

  • SQL Server 2016 och senare
  • Azure SQL Database
  • Azure Synapse Analytics (dedikerad SQL-pool)
  • Azure Synapse Analytics (serverlös SQL-pool) stöds inte

Skapa SQL-tabell och -data

Skapa en tabell med fiktiva data som ska användas i det här exempelscenariot.

  1. Anslut till SQL-databasen med den klient eller det verktyg du föredrar.

  2. Skapa en tabell med namnet Revenues med idkolumnerna , category, revenueoch 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. Infoga fyra exempelrader i Revenues tabellen.

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

    I det här exemplet accessible_role lagrar kolumnen det rollnamn som kan komma åt raden.

Tips/Råd

Vanliga användningsfall för sessionskontext:

  • Rollbaserad filtrering (visas här) med hjälp av roles
  • Isolering av flera klientorganisationer med hjälp av tenant_id
  • Användarspecifik filtrering med hjälp av user_id
  1. Testa dina data med en enkel SELECT * fråga.

    SELECT * FROM dbo.Revenues
    
  2. Skapa en funktion med namnet RevenuesPredicate. Den här funktionen filtrerar resultat baserat på den aktuella sessionskontexten.

    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. Skapa en säkerhetsprincip med namnet RevenuesSecurityPolicy med funktionen .

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

Anmärkning

WITH SCHEMABINDING Satsen krävs för funktioner som används i säkerhetsprinciper så att underliggande schemaändringar inte ogiltigförklarar predikatet.

(Valfritt) Skapa en lagrad procedur

Det här avsnittet visar ett enkelt "hello world"-mönster för att använda sessionskontextvärden direkt i T-SQL.

  1. Skapa en lagrad procedur som läser roles sessionskontextvärdet och använder det för att filtrera resultat.

    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
    

Kör verktyget

Kör verktyget Data API Builder (DAB) för att generera en konfigurationsfil och en enda entitet.

  1. Skapa en ny konfiguration genom att ställa in --set-session-context till true.

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

    När sessionskontexten är aktiverad för SQL Server skickar Data API Builder autentiserade användaranspråk till SQL genom att anropa sp_set_session_context (till exempel roles). Om du aktiverar sessionskontext inaktiveras även cachelagring av svar för datakällan.

Varning

När set-session-context är aktiverat inaktiveras cachelagring av svar för datakällan. För scenarier med hög trafik bör du överväga att testa prestanda, indexera predikatkolumnen eller använda databasprinciper för Data API Builder när de uppfyller dina behov.

  1. Lägg till en ny entitet med namnet revenue för dbo.Revenues tabellen.

    dab add revenue \
        --source "dbo.Revenues" \
        --permissions "Authenticated:read"
    
  2. Starta verktyget Data API Builder.

    dab start
    
  3. Gör en förfrågan till slutpunkten utan att ange en giltig roll. Observera att inga data returneras eftersom:

    • Den effektiva rollen är som standard Authenticated.
    • Inga rader har accessible_role = 'Authenticated'.
    • Säkerhetsprincipen filtrerar resultat när rollen inte matchar.
    curl http://localhost:5000/api/revenue
    
  4. Skicka en förfrågan till slutpunkten och ställ in den effektiva rollen till Oscar. Observera att de filtrerade resultaten endast innehåller raderna Oscar .

    curl -H "X-MS-API-ROLE: Oscar" http://localhost:5000/api/revenue
    
  5. Använd Hannah rollen igen.

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

Testa med GraphQL

Sessionskontext fungerar också med GraphQL-frågor.

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

Skicka rollrubriken:

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 } } }"}'

Vad data-API-byggare skickar till SQL Server

När sessionskontexten är aktiverad anger Data API Builder sessionskontextvärden för varje begäran innan du kör frågan.

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

Alla autentiserade användaranspråk skickas i form av nyckel-värde-par. Vanliga påståenden är roles, sub eller oid och eventuella anpassade påståenden från din identitetsleverantör.

Testa i SQL

Testa filtret och predikatet i SQL direkt för att säkerställa att det fungerar.

  1. Anslut till SQL-servern igen med den klient eller det verktyg du föredrar.

  2. Kör sp_set_session_context för att manuellt ange sessionskontextens roles krav till det statiska värdet Oscar.

    EXEC sp_set_session_context 'roles', 'Oscar';
    
  3. Kör en typisk SELECT * fråga. Observera att resultaten filtreras automatiskt med hjälp av predikatet.

    SELECT * FROM dbo.Revenues;  
    
  4. (Valfritt) Fråga tabellen med hjälp av den lagrade proceduren.

    EXEC dbo.GetRevenuesForCurrentRole;
    

Rensa resurser

Om du vill ta bort exempelobjekten kör du:

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;

Felsökning

  • Inga resultat returnerades: Kontrollera att säkerhetsprincipen är aktiv (SELECT * FROM sys.security_policies), kontrollera sessionskontextvärdet (SELECT SESSION_CONTEXT(N'roles')) och bekräfta att --set-session-context true den har angetts i konfigurationen för Data API Builder.
  • Alla rader som returneras: Bekräfta att säkerhetsprincipen inte är inaktiverad (WITH STATE = OFF) och att predikatet endast returnerar 1 för auktoriserade rader.
  • Prestandaproblem: Indexera predikatkolumnen (accessible_role) och överväg att tillfälligt inaktivera principen för att isolera prestandapåverkan.