前言:
眼前姐妹们对“oracleschemabinding”大概比较关注,大家都想要了解一些“oracleschemabinding”的相关资讯。那么小编在网络上网罗了一些有关“oracleschemabinding””的相关资讯,希望兄弟们能喜欢,我们一起来了解一下吧!之前有朋友提到数据的隔离,这里先介绍一种传统SQL的隔离:RLS的隔离。
1. 应用层:在SESSION_CONTEXT中设置 TenantId
首先,使用数据库客户端库的数据相关路由 API 连接到分片数据库。应用程序仍必须告知数据库哪个 TenantId 正在使用连接。TenantId 告知 RLS 安全策略哪些行必须筛选为属于其他租户。将当前租户 ID 存储在连接的SESSION_CONTEXT中。
SESSION_CONTEXT的替代方法是使用CONTEXT_INFO。但SESSION_CONTEXT是更好的选择。SESSION_CONTEXT更易于使用,但它默认返回 NULL,并且支持键值对。zai
在返回connection前把SESSION_CONTEXT附加到connection上:
cmd.CommandText = @"exec sp_set_session_context @key=N'TenantId', @value=@shardingKey"; cmd.Parameters.AddWithValue("@shardingKey", shardingKey); cmd.ExecuteNonQuery();2. 数据层:创建行级别安全策略创建安全策略以筛选每个租户可以访问的行
现在,应用程序在查询之前使用当前 TenantId 设置SESSION_CONTEXT,RLS 安全策略可以筛选查询并排除具有不同 TenantId 的行。
RLS 在 Transact-SQL 中实现。用户定义的函数定义访问逻辑,安全策略将此函数绑定到任意数量的表。对于此项目:
该函数验证应用程序是否已连接到数据库,以及存储在SESSION_CONTEXT中的 TenantId 是否与给定行的 TenantId 匹配。应用程序已连接,而不是其他某个 SQL 用户。筛选器谓词允许满足 TenantId 筛选器的行通过选择、更新和删除查询。BLOCK 谓词可防止未通过筛选器的行入或更新。如果尚未设置SESSION_CONTEXT,则该函数返回 NULL,并且没有行可见或无法插入。
若要在所有分片上启用 RLS,可以看一下此 T-SQL。创建一个policy 去过滤数据。
CREATE SCHEMA rls; -- Separate schema to organize RLS objects.GOCREATE FUNCTION rls.fn_tenantAccessPredicate(@TenantId int) RETURNS TABLE WITH SCHEMABINDINGAS RETURN SELECT 1 AS fn_accessResult -- Use the user in your application's connection string. -- Here we use 'dbo' only for demo purposes! WHERE DATABASE_PRINCIPAL_ID() = DATABASE_PRINCIPAL_ID('dbo') AND CAST(SESSION_CONTEXT(N'TenantId') AS int) = @TenantId;GOCREATE SECURITY POLICY rls.tenantAccessPolicy ADD FILTER PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Blogs, ADD BLOCK PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Blogs, ADD FILTER PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Posts, ADD BLOCK PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Posts;GO
如果稍后添加新表,请更改安全策略以在新表上添加 FILTER 和 BLOCK 谓词。
ALTER SECURITY POLICY rls.tenantAccessPolicy ADD FILTER PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.MyNewTable, ADD BLOCK PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.MyNewTable;GO添加默认约束以自动填充插入的租户 ID
可以在每个表上放置默认约束,以便在插入行时使用当前存储在SESSION_CONTEXT中的值自动填充 TenantId。下面是一个示例。
-- Create default constraints to auto-populate TenantId with the-- value of SESSION_CONTEXT for inserts.ALTER TABLE Blogs ADD CONSTRAINT df_TenantId_Blogs DEFAULT CAST(SESSION_CONTEXT(N'TenantId') AS int) FOR TenantId;GOALTER TABLE Posts ADD CONSTRAINT df_TenantId_Posts DEFAULT CAST(SESSION_CONTEXT(N'TenantId') AS int) FOR TenantId;GO
标签: #oracleschemabinding