在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管理工作室运行它,一切工作,我得到预期的行。

有人能帮我吗?我不知道我做错了什么。

在SQL Server 2016中实现NHibernate的级别安全

我知道这个问题很老了,但也许我的答案会帮助别人。当我使用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);
}