在SQL Server 2016中实现NHibernate的级别安全
本文关键字:安全 NHibernate 实现 SQL Server 2016 | 更新日期: 2023-09-27 18:08:59
我正在尝试使用Nhibernate在SQL Server中实现行级安全。我想使用这个方法:https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-entity-framework-row-level-security/。
我在nhibernate中创建了一个拦截器:
public class TenantInterceptor : EmptyInterceptor
{
private readonly ITenantResolver _tenantResolver;
public TenantInterceptor(ITenantResolver tenantResolver)
{
_tenantResolver = tenantResolver;
}
public override void SetSession(ISession session)
{
string tenant = "sampleTenant";
if (_tenantResolver.Current != null)
tenant = _tenantResolver.Current.Id;
string queryFormat = @"Exec sp_set_session_context @key=N'@Tenant', @value='{0}'";
string query = string.Format(queryFormat, tenant);
session.CreateSQLQuery(query)
.ExecuteUpdate();
base.SetSession(session);
}
}
我以这种方式将它附加到会话中:
if (!CurrentSessionContext.HasBind(GetSessionFactory()))
{
_session = GetSessionFactory().OpenSession(new TenantInterceptor(_tenantResolver));
CurrentSessionContext.Bind(_session);
}
else
{
_session = GetSessionFactory().OpenSession(new TenantInterceptor(_tenantResolver));
}
,我也有以下代码在SQL Server:
CREATE SCHEMA [Security]
go
CREATE FUNCTION [Security].tenantAccessPredicate(@Tenant nvarchar(255))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
SELECT 1 AS accessResult
WHERE @Tenant = CAST(SESSION_CONTEXT(N'@Tenant') AS nvarchar(255)) OR @Tenant = ''
所以我认为我做的一切都是对的。但是当我从应用程序运行查询时,我从未收到任何行。当我复制完全相同的SQL代码,并从SQL Server管理工作室运行它,一切工作,我得到预期的行。
有人能帮我吗?我不知道我做错了什么。
我知道这个问题很老了,但也许我的答案会帮助别人。当我使用ADO时,它为我工作。. NET的API而不是NHibernate的:
public override void SetSession(ISession session)
{
using (var cmd = session.Connection.CreateCommand())
{
var param1 = cmd.CreateParameter();
param1.ParameterName = "@key";
param1.Value = "TenantId";
var param2 = cmd.CreateParameter();
param2.ParameterName = "@value";
param2.Value = _tenantResolver.Current.Id;
cmd.CommandText = "sp_set_session_context";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(param1);
cmd.Parameters.Add(param2);
cmd.ExecuteNonQuery();
}
base.SetSession(session);
}