Udostępnij przez


Implementowanie zabezpieczeń na poziomie wiersza z kontekstem sesji w Data API Builder

Użyj funkcji kontekstu sesji języka SQL, aby zaimplementować zabezpieczenia na poziomie wiersza w narzędziu Data API Builder.

Diagram przedstawiający sposób ustawiania kontekstu sesji SQL przez konstruktora interfejsu API danych w celu włączenia zabezpieczeń na poziomie wiersza.

Ważne

Kontekst sesji z zabezpieczeniami na poziomie wiersza programu SQL Server różni się od zasad bazy danych konstruktora interfejsu API danych. Zasady bazy danych (na przykład --policy-database "@item.owner eq @claims.user_id") są tłumaczone na klauzule WHERE przez Kompilator interfejsu API danych, podczas gdy kontekst sesji przekazuje oświadczenia do serwera SQL Server, aby natywne zabezpieczenia na poziomie wiersza obsługiwały filtrowanie.

Wymagania wstępne

  • Istniejący serwer SQL i baza danych.
  • Kreator interfejsu wiersza polecenia do API danych. Zainstaluj CLI

Uwaga / Notatka

Kontekst sesji jest obsługiwany w:

  • SQL Server 2016 i nowsze
  • Azure SQL Database
  • Azure Synapse Analytics (Dedykowana pula SQL)
  • Usługa Azure Synapse Analytics (bezserwerowa pula SQL) nie jest obsługiwana

Tworzenie tabeli i danych SQL

Utwórz tabelę z fikcyjnymi danymi do użycia w tym przykładowym scenariuszu.

  1. Nawiąż połączenie z bazą danych SQL przy użyciu preferowanego klienta lub narzędzia.

  2. Utwórz tabelę o nazwie Revenues z kolumnami id, category, revenuei 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. Wstaw cztery przykładowe wiersze do Revenues tabeli.

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

    W tym przykładzie kolumna accessible_role przechowuje nazwę roli, która może uzyskać dostęp do wiersza.

Wskazówka

Typowe przypadki użycia kontekstu sesji:

  • Filtrowanie oparte na rolach (pokazane tutaj) przy użyciu roles
  • Izolacja w środowiskach wielodostępności przy użyciu tenant_id
  • Filtrowanie specyficzne dla użytkownika przy użyciu user_id
  1. Przetestuj dane przy użyciu prostego SELECT * zapytania.

    SELECT * FROM dbo.Revenues
    
  2. Utwórz funkcję o nazwie RevenuesPredicate. Ta funkcja będzie filtrować wyniki na podstawie bieżącego kontekstu sesji.

    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. Utwórz zasady zabezpieczeń o nazwie RevenuesSecurityPolicy przy użyciu funkcji .

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

Uwaga / Notatka

Klauzula WITH SCHEMABINDING jest wymagana dla funkcji używanych w zasadach zabezpieczeń, aby zmiany w podstawowej strukturze schematu nie prowadziły do unieważnienia predykatu.

(Opcjonalnie) Utwórz procedurę składowaną

W tej sekcji przedstawiono prosty wzorzec "hello world" umożliwiający używanie wartości kontekstu sesji bezpośrednio w języku T-SQL.

  1. Utwórz procedurę składowaną, która odczytuje roles wartość kontekstu sesji i używa jej do filtrowania wyników.

    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
    

Uruchamianie narzędzia

Uruchom narzędzie konstruktora interfejsu API danych (DAB), aby wygenerować plik konfiguracji i jedną jednostkę.

  1. Utwórz nową konfigurację przez ustawienie --set-session-context na prawdę.

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

    Gdy kontekst sesji jest włączony dla programu SQL Server, konstruktor interfejsu API danych wysyła uwierzytelnione oświadczenia użytkownika do bazy danych SQL przez wywołanie metody sp_set_session_context (na przykład roles). Włączenie kontekstu sesji powoduje również wyłączenie buforowania odpowiedzi dla tego źródła danych.

Ostrzeżenie

Po set-session-context włączeniu buforowanie odpowiedzi jest wyłączone dla źródła danych. W przypadku scenariuszy o dużym natężeniu ruchu rozważ przetestowanie wydajności, indeksowanie kolumny predykatu lub użycie zasad bazy danych Data API Builder, jeśli spełniają Twoje wymagania.

  1. Dodaj nową jednostkę o nazwie revenue dla dbo.Revenues tabeli.

    dab add revenue \
        --source "dbo.Revenues" \
        --permissions "Authenticated:read"
    
  2. Uruchom narzędzie konstruktora interfejsu API danych.

    dab start
    
  3. Wykonywanie zapytań względem punktu końcowego bez określania efektywnej roli. Zwróć uwagę, że żadne dane nie są zwracane, ponieważ:

    • Obowiązująca rola jest domyślnie ustawiona na Authenticated.
    • Nie ma wierszy z accessible_role = 'Authenticated'.
    • Polityka zabezpieczeń filtruje wyniki, gdy rola nie pasuje.
    curl http://localhost:5000/api/revenue
    
  4. Wykonaj zapytanie względem punktu końcowego, ustawiając obowiązującą rolę na Oscar. Zwróć uwagę, że przefiltrowane wyniki zawierają tylko Oscar wiersze.

    curl -H "X-MS-API-ROLE: Oscar" http://localhost:5000/api/revenue
    
  5. Powtarzaj, korzystając z roli Hannah.

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

Testowanie przy użyciu języka GraphQL

Kontekst sesji współdziała również z zapytaniami GraphQL.

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

Przekaż nagłówek roli:

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

Co konstruktor interfejsu API danych wysyła do programu SQL Server

Po włączeniu kontekstu sesji konstruktor interfejsu API danych ustawia wartości kontekstu sesji na każdym żądaniu przed wykonaniem zapytania.

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

Wszystkie oświadczenia uwierzytelnionych użytkowników są wysyłane jako pary klucz-wartość. Typowe oświadczenia obejmują roles, sub lub oid, a także wszelkie niestandardowe oświadczenia od dostawcy tożsamości.

Testowanie w programie SQL

Przetestuj filtr i predykat bezpośrednio w języku SQL, aby upewnić się, że działa.

  1. Połącz się ponownie z serwerem SQL przy użyciu preferowanego klienta lub narzędzia.

  2. Uruchom sp_set_session_context, aby ręcznie ustawić żądanie kontekstu sesji roles na statyczną wartość Oscar.

    EXEC sp_set_session_context 'roles', 'Oscar';
    
  3. Uruchom typowe SELECT * zapytanie. Zwróć uwagę, że wyniki są automatycznie filtrowane przy użyciu predykatu.

    SELECT * FROM dbo.Revenues;  
    
  4. (Opcjonalnie) Wykonaj zapytanie dla tabeli przy użyciu procedury składowanej.

    EXEC dbo.GetRevenuesForCurrentRole;
    

Uprzątnij zasoby

Jeśli chcesz usunąć przykładowe obiekty, uruchom polecenie:

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;

Rozwiązywanie problemów

  • Nie są zwracane żadne wyniki: Sprawdź, czy zasady zabezpieczeń są aktywne (SELECT * FROM sys.security_policies), sprawdź wartość kontekstu sesji (SELECT SESSION_CONTEXT(N'roles')) i potwierdź, że --set-session-context true ustawiono w konfiguracji konstruktora interfejsu API danych.
  • Zwrócone wszystkie wiersze: Upewnij się, że zasady zabezpieczeń nie są wyłączone (WITH STATE = OFF) i że predykat zwraca 1 tylko dla autoryzowanych wierszy.
  • Problemy z wydajnością: zaindeksuj kolumnę predykatu (accessible_role) i rozważ czasowo wyłączenie polityki, aby odizolować wpływ na wydajność.