SQL의 세션 컨텍스트 기능을 사용하여 데이터 API 작성기에서 행 수준 보안을 구현합니다.
중요합니다
SQL Server 행 수준 보안을 사용하는 세션 컨텍스트는 데이터 API 작성기 데이터베이스 정책과 다릅니다. 데이터베이스 정책(예: --policy-database "@item.owner eq @claims.user_id")은 데이터 API 작성기에 의해 WHERE 절로 변환되고 세션 컨텍스트는 SQL 네이티브 행 수준 보안이 필터링을 처리하도록 SQL Server에 클레임을 전달합니다.
필수 조건
- 기존 SQL 서버 및 데이터베이스.
- 데이터 API 작성기 CLI. CLI 설치
비고
세션 컨텍스트는 다음에서 지원됩니다.
- SQL Server 2016 이상
- Azure SQL 데이터베이스
- Azure Synapse Analytics(전용 SQL 풀)
- Azure Synapse Analytics(서버리스 SQL 풀)는 지원되지 않습니다.
SQL 테이블 및 데이터 만들기
이 예제 시나리오에서 사용할 가상 데이터가 있는 테이블을 만듭니다.
기본 설정 클라이언트 또는 도구를 사용하여 SQL 데이터베이스에 연결합니다.
Revenues이라는 이름의 테이블을id,category,revenue,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 ); GORevenues테이블에 네 개의 샘플 행을 삽입합니다.INSERT INTO dbo.Revenues VALUES (1, 'Book', 5000, 'Oscar'), (2, 'Comics', 10000, 'Oscar'), (3, 'Journals', 20000, 'Hannah'), (4, 'Series', 40000, 'Hannah') GO이 예제에서 열은
accessible_role행에 액세스할 수 있는 역할 이름을 저장합니다.
팁 (조언)
일반적인 세션 컨텍스트 사용 사례:
- 역할 기반 필터링(여기에 표시됨)을 사용하여
roles -
tenant_id를 사용하여 다중 테넌트 격리 -
user_id을 사용한 사용자별 필터링
간단한
SELECT *쿼리로 데이터를 테스트합니다.SELECT * FROM dbo.RevenuesRevenuesPredicate함수를 만듭니다. 이 함수는 현재 세션 컨텍스트에 따라 결과를 필터링합니다.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));함수를 사용하여 명명된 보안 정책을 만듭니다
RevenuesSecurityPolicy.CREATE SECURITY POLICY dbo.RevenuesSecurityPolicy ADD FILTER PREDICATE dbo.RevenuesPredicate(accessible_role) ON dbo.Revenues;
비고
이 WITH SCHEMABINDING 절은 보안 정책에 사용되는 함수에 필요하므로 기본 스키마 변경으로 조건자가 무효화되지 않습니다.
(선택 사항) 저장 프로시저 만들기
이 섹션에서는 T-SQL에서 직접 세션 컨텍스트 값을 사용하기 위한 간단한 "hello world" 패턴을 보여 줍니다.
세션 컨텍스트 값을 읽고
roles이를 사용하여 결과를 필터링하는 저장 프로시저를 만듭니다.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
도구 실행
DAB(Data API Builder) 도구를 실행하여 구성 파일 및 단일 엔터티를 생성합니다.
새 구성을 만들 때
--set-session-context을 true로 설정하십시오.dab init \ --database-type mssql \ --connection-string "<sql-connection-string>" \ --set-session-context true \ --auth.provider SimulatorSQL Server에 대해 세션 컨텍스트를 사용하도록 설정하면 Data API Builder는 호출
sp_set_session_context하여 인증된 사용자 클레임을 SQL로 보냅니다(예:roles). 세션 컨텍스트를 사용하도록 설정하면 해당 데이터 원본에 대한 응답 캐싱도 사용하지 않도록 설정됩니다.
경고
사용하도록 설정하면 set-session-context 데이터 원본에 대한 응답 캐싱이 비활성화됩니다. 트래픽이 많은 시나리오의 경우 요구 사항을 충족하는 경우 성능 테스트, 조건자 열 인덱싱 또는 Data API 작성기 데이터베이스 정책을 사용하는 것이 좋습니다.
테이블에 이름이 지정된
revenue새 엔터티를 추가합니다dbo.Revenues.dab add revenue \ --source "dbo.Revenues" \ --permissions "Authenticated:read"데이터 API 작성기 도구를 시작합니다.
dab start효과적인 역할을 지정하지 않고 엔드포인트를 쿼리합니다. 다음과 같은 이유로 데이터가 반환되지 않는지 확인합니다.
- 유효 역할은 기본적으로 .로 설정
Authenticated됩니다. -
accessible_role = 'Authenticated'라는 행이 없습니다. - 보안 정책은 역할이 일치하지 않을 때 결과를 필터링합니다.
curl http://localhost:5000/api/revenue- 유효 역할은 기본적으로 .로 설정
Oscar으로 유효한 역할을 설정하면서 엔드포인트를 쿼리합니다. 필터링된 결과에Oscar행만 포함되어 있는지 확인합니다.curl -H "X-MS-API-ROLE: Oscar" http://localhost:5000/api/revenueHannah역할을 사용하여 반복합니다.curl -H "X-MS-API-ROLE: Hannah" http://localhost:5000/api/revenue
GraphQL을 사용하여 테스트
세션 컨텍스트는 GraphQL 쿼리에서도 작동합니다.
query {
revenues {
items {
id
category
revenue
accessible_role
}
}
}
역할 헤더를 전달합니다.
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 } } }"}'
Data API Builder가 SQL Server에 보내는 내용
세션 컨텍스트를 사용하도록 설정하면 데이터 API 작성기는 쿼리를 실행하기 전에 모든 요청에서 세션 컨텍스트 값을 설정합니다.
EXEC sp_set_session_context 'roles', 'Oscar', @read_only = 0;
-- Then executes your query
SELECT * FROM dbo.Revenues;
인증된 모든 사용자 클레임은 키-값 쌍으로 전송됩니다. 일반적인 클레임에는 roles, sub, oid 또는 ID 공급자의 사용자 지정 클레임이 포함됩니다.
SQL에서 테스트
필터를 테스트하고 SQL에서 조건자를 직접 테스트하여 작동하는지 확인합니다.
원하는 클라이언트 또는 도구를 사용하여 SQL Server에 다시 연결합니다.
sp_set_session_context를 실행하여 세션 컨텍스트의roles클레임을 정적 값Oscar로 수동 설정하세요.EXEC sp_set_session_context 'roles', 'Oscar';일반적인
SELECT *쿼리를 실행합니다. 결과가 조건자를 사용하여 자동으로 필터링되는지 확인합니다.SELECT * FROM dbo.Revenues;(선택 사항) 저장 프로시저를 사용하여 테이블을 쿼리합니다.
EXEC dbo.GetRevenuesForCurrentRole;
자원을 정리하세요
샘플 개체를 제거하려면 다음을 실행합니다.
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
-
결과가 반환되지 않음: 보안 정책이 활성 상태인지(), 세션 컨텍스트 값(
SELECT * FROM sys.security_policies)을 확인하고,SELECT SESSION_CONTEXT(N'roles')Data API 작성기 구성에서 설정되었는지 확인--set-session-context true합니다. -
반환된 모든 행: 보안 정책이 비활성화되지 않고
WITH STATE = OFF조건자가 권한 있는 행에 대해서만1을 반환하는지 확인하십시오. -
성능 문제: 조건자 열(
accessible_role)을 인덱싱하고, 성능 영향을 격리하기 위해 정책을 일시적으로 사용하지 않도록 설정하는 것이 좋습니다.
관련 콘텐츠
- 데이터베이스별 기능
환경들 사용