Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何获取Azure SQL中审核字段的用户的SUSER_NAME()_Sql Server_Entity Framework Core_Azure Active Directory_Azure Sql Database - Fatal编程技术网

Sql server 如何获取Azure SQL中审核字段的用户的SUSER_NAME()

Sql server 如何获取Azure SQL中审核字段的用户的SUSER_NAME(),sql-server,entity-framework-core,azure-active-directory,azure-sql-database,Sql Server,Entity Framework Core,Azure Active Directory,Azure Sql Database,我们正在从on-prem数据库迁移到Azure SQL。我们在数据库中有审计字段,每当发生DML事务(即插入、更新、删除-软删除)时,这些字段都会获取SUSER\u NAME()。由于on-prem数据库使用Windows域Active Directory,并且用户使用集成安全性登录到数据库,因此我们可以正确获取当前用户名 但是,当我们在Azure SQL中使用托管标识时,SUSER\u NAME()可以归结为两个guid的串联:托管标识guid和服务容器guid。因此,我们正在丢失当前用户的用

我们正在从on-prem数据库迁移到Azure SQL。我们在数据库中有审计字段,每当发生DML事务(即插入、更新、删除-软删除)时,这些字段都会获取
SUSER\u NAME()
。由于on-prem数据库使用Windows域Active Directory,并且用户使用集成安全性登录到数据库,因此我们可以正确获取当前用户名

但是,当我们在Azure SQL中使用托管标识时,
SUSER\u NAME()
可以归结为两个
guid
的串联:托管标识
guid
和服务容器
guid
。因此,我们正在丢失当前用户的用户名。是否可以使用SQL函数
SUSER_name()
(或其他一些SQL函数)获取用户名,或者这是一个代码更改,我们现在将实际用户名传递给相关审计字段,以调用Azure SQL数据库

更新1:

我们的应用程序设计为使用以下
DbContext
构造函数与Azure SQL交互:

public SomeDbEntities(IConfiguration objConfiguration, AzureAuthenticationInterceptor azureAuthenticationInterceptor) :
    base(new DbContextOptionsBuilder<SomeDbEntities>()
        .UseSqlServer(objConfiguration.GetValue<string>("Azure:ConnectionStrings:SomeDbEntities"))
        .AddInterceptors(azureAuthenticationInterceptor)
        .Options)
{ }
公共SomeDbEntities(IConfiguration对象配置、AzureAuthenticationInterceptor AzureAuthenticationInterceptor):
基本(新的DbContextOptionsBuilder()
.UseSqlServer(objConfiguration.GetValue(“Azure:ConnectionString:SomeDbEntities”))
.AddInterceptors(azureAuthenticationInterceptor)
(可选)
{ }
我们正在使用一个
azureAuthenticationInterceptor
来处理线程阻塞问题。这里提供了解决方案:

更新2:


审核字段是由
触发器使用
SUSER\u NAME()
函数设置的,该函数将数据记录到历史记录表中。

由于您使用服务Prinicpal连接到Azure SQL,因此您必须以某种方式传递AAD用户的身份。您可以使用自定义表,也可以在每次连接时调用

下面是使用sp_set_session_context设置最终用户身份的DbContext示例:

public class Order
{
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }
    public DateTime OrderDate { get; set; }
    public string CreatedBy { get; set; }

}

使用Microsoft.AspNetCore.Http;
使用Microsoft.EntityFrameworkCore;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
命名空间SessionContextSample.Models
{
公共类OrderContext:DbContext
{
public OrderContext(IHttpContextAccessor ctxt,DbContextOptions opts):基本(opts)
{
//如果在HttpRequest之外运行,如在启动时运行迁移或在后台工作程序中运行迁移,请跳过此步骤
if(ctxt.HttpContext!=null)
{
var userName=ctxt.HttpContext.User.Identity.Name??“未知”;
//打开数据库连接。它将在此web请求的生存期内保持打开状态
this.Database.GetDbConnection().Open();
this.Database.ExecuteSqlRaw(“EXEC sys.sp_set_session_context@key=N'user',@value={0};”,用户名);
}
}
公共数据库集命令{get;set;}
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
基本配置(选项生成器);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity().Property(o=>o.CreatedBy)
.HasDefaultValueSql(“转换(会话上下文(N'user))为nvarchar(255)))
.ValueGeneratedOnAdd()
.HasMaxLength(255)
.IsRequired();
基于模型创建(modelBuilder);
}
}
}

如果您打开(),则连接EF将保持打开状态,直到释放DbContext(在您的作用域/WebRequest结束时)。

由于您使用服务Prinicpal连接到Azure SQL,因此您必须以某种方式传递AAD用户的身份。您可以使用自定义表,也可以在每次连接时调用

下面是使用sp_set_session_context设置最终用户身份的DbContext示例:

public class Order
{
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }
    public DateTime OrderDate { get; set; }
    public string CreatedBy { get; set; }

}

使用Microsoft.AspNetCore.Http;
使用Microsoft.EntityFrameworkCore;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
命名空间SessionContextSample.Models
{
公共类OrderContext:DbContext
{
public OrderContext(IHttpContextAccessor ctxt,DbContextOptions opts):基本(opts)
{
//如果在HttpRequest之外运行,如在启动时运行迁移或在后台工作程序中运行迁移,请跳过此步骤
if(ctxt.HttpContext!=null)
{
var userName=ctxt.HttpContext.User.Identity.Name??“未知”;
//打开数据库连接。它将在此web请求的生存期内保持打开状态
this.Database.GetDbConnection().Open();
this.Database.ExecuteSqlRaw(“EXEC sys.sp_set_session_context@key=N'user',@value={0};”,用户名);
}
}
公共数据库集命令{get;set;}
配置时受保护的覆盖无效(DBContextOptions Builder Options Builder)
{
基本配置(选项生成器);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity().Property(o=>o.CreatedBy)
.HasDefaultValueSql(“转换(会话上下文(N'user))为nvarchar(255)))
.ValueGeneratedOnAdd()
.HasMaxLength(255)
.IsRequired();
基于模型创建(modelBuilder);
}
}
}
如果您打开()连接EF将使其保持打开状态,直到DbContext被释放(在您的作用域/WebRequest结束时)。

我还没有研究“您能告诉我如何以我已经尝试的方式解决这个问题”方法。我知道你可以