背景
我有一个在 Http.sys 中运行的 ASP.NET Core 应用程序来提供 Windows 身份验证。
我的应用程序的客户端使用 Windows 身份验证,并且在首次访问该站点时会提示用户输入他们的 Windows 登录凭据。一切都很好。
我正在使用由实体框架使用代码优先方法构建的 SQL Server 数据库(托管在与应用程序相同的服务器上)。在startup.cs
文件中,我正在运行一个dbContext.migrate()
以确保数据库是最新的,然后应用程序继续正常运行。
问题
当远程用户与站点交互并执行需要访问数据库的操作时,我希望在他们的用户名下执行该数据库事务。
例如,如果我在我的服务器上运行 Asp.net 核心应用程序User1
,然后从登录的用户计算机访问 webapp,因为User2
数据库交互仍在执行,User1
因为该用户是运行主应用程序的用户。
我希望有可能使数据库交互由User2
而不是User1
在这种情况下执行。主要是为了记录和分析的目的。
在检索实例时,dbContext
我向它提供了一个连接字符串,该字符串声明使用 SSPI 进行身份验证。有没有办法将远程用户的用户名包含到此连接中,以便他们以自己的身份连接到数据库?我可以轻松地从我的控制器中检索远程用户的凭据/用户名。我相信我可以使用一种叫做的东西,Impersonation
但我不确定实现它的最佳实践,或者它是否是推荐的解决方案。
任何帮助将不胜感激。
更新
感谢一些有用的反馈,我尝试实现以下功能:
我的连接字符串设置如下startup.cs
:
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(@"Server=MyServer\MSSQLSERVER;Database=MyDatabase;Trusted_Connection=True;"));
然后我在我的控制器/类中执行这样的操作:
var values = new List<Values>();
WindowsIdentity.RunImpersonated(user.AccessToken, () =>
{
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseSqlServer(@"Server=MyServer\MSSQLSERVER;Database=MyDatabase;Trusted_Connection=True;");
using (var ctx = new MyDbContext(optionsBuilder.Options))
{
values = (from row in ctx.Table select row).OrderBy(x => x.Id).ToList();
}
});
变量被传递到函数中user
并且是类型WindowsIdentity
。
从 localhost 执行代码可以正常工作,但是当远程用户尝试时,它会返回以下错误:System.Data.SqlClient.SqlException: 'A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - No such host is known.)
更新 2
我设法通过使用连接字符串的 IP 地址而不是服务器/机器名称来解决此错误。所以现在我的连接字符串如下所示:
@"Server=<IP address>\MSSQLSERVER;Database=ConfigDb;Trusted_Connection=True
现在我面临 SQL Server 声明的另一个问题No connection could be made because the target machine actively refused it
。我可以通过 SQL Management Studio 使用此用户连接到 SQL Server,但不能通过我的应用程序。
我在 EventViewer 中发现实际错误与 SSPI: 相关SSPI handshake failed with error code 0x8009030c, state 14 while establishing a connection with integrated security; the connection has been closed. Reason: AcceptSecurityContext failed. The operating system error code indicates the cause of failure. The logon attempt failed [CLIENT: <named pipe>]
。不太确定为什么这会失败。