ASP.Net 身份丢失假冒
ASP.Net Identity losing Impersonation
我有很多问题,每当我调用 ASP.Net Identity Async 方法时,我都会从 SQL 服务器收到访问被拒绝的异常。
以下returns个用户:
var user = (from u in ctx.Users
where u.Id == 1
select u).FirstOrDefault();
而
var user = await userManager.FindByIdAsync(1);
触发异常
System.Data.SqlClient.SqlException: Login failed for user 'DOMAIN\MACHINE$'.
似乎正在发生的事情是我们的 web.config configuration/system.web 部分
中有以下行
<identity impersonate="true" userName="DOMAIN\Domain User" password="xxx" />
此模拟用户有权访问 SQL 服务器数据库,但应用程序池用户没有。似乎每当我在 ASP.Net Identity 中调用异步方法时,它都会退回到应用程序池用户并失去模拟。
我确实找到了一个听起来类似的问题,并在此处进行了解释
这也会导致我的问题吗?
除了将应用程序池用户更改为具有数据库访问权限的用户之外,还有其他解决方法吗?
使用 web.config 设置模拟用户是否是一种旧的做事方式,现在是一种糟糕的做法?
编辑:经过进一步调查,我发现了这些文章
http://www.hanselman.com/blog/AvoidUsingImpersonationInASPNET.aspx
http://blog.codeishard.net/2012/09/17/await-async-mvc-and-impersonation/
除非有人告诉我其他情况,否则使用模拟似乎不是个好主意。
集成管道模式不再支持模拟。尤其是在使用异步方法时。
原因是 Impersonation 发生在线程上,当你调用一个异步函数时,它可能实际上在不同的线程上执行或return。
您应该使用 WindowsImpersonationContext 来包装您的数据库调用。
using System.Security.Principal;
...
//Get the identity of the current user
IIdentity contextId = HttpContext.Current.User.Identity;
WindowsIdentity userId = (WindowsIdentity)contextId;
//Temporarily impersonate
using (WindowsImpersonationContext imp = userId.Impersonate())
{
//Perform tasks using the caller's security context
DoSecuritySensitiveTasks();
}
确保在 using 块中执行此操作,因为如果代码中出现未捕获的异常,您最终将无法恢复原始上下文,并产生安全问题。
我最后的解决方案是在应用程序池中设置用户,而不是使用模拟。
这似乎与在具有同等安全性的 Web.config 中设置模拟具有完全相同的效果,只是在使用 Async 时没有问题。
正如@Erik 在他的回答中所说,似乎不再支持模拟,并且根据 http://www.hanselman.com/blog/AvoidUsingImpersonationInASPNET.aspx
它从来没有被鼓励放在首位。
我有很多问题,每当我调用 ASP.Net Identity Async 方法时,我都会从 SQL 服务器收到访问被拒绝的异常。
以下returns个用户:
var user = (from u in ctx.Users
where u.Id == 1
select u).FirstOrDefault();
而
var user = await userManager.FindByIdAsync(1);
触发异常
System.Data.SqlClient.SqlException: Login failed for user 'DOMAIN\MACHINE$'.
似乎正在发生的事情是我们的 web.config configuration/system.web 部分
中有以下行<identity impersonate="true" userName="DOMAIN\Domain User" password="xxx" />
此模拟用户有权访问 SQL 服务器数据库,但应用程序池用户没有。似乎每当我在 ASP.Net Identity 中调用异步方法时,它都会退回到应用程序池用户并失去模拟。
我确实找到了一个听起来类似的问题,并在此处进行了解释
这也会导致我的问题吗?
除了将应用程序池用户更改为具有数据库访问权限的用户之外,还有其他解决方法吗?
使用 web.config 设置模拟用户是否是一种旧的做事方式,现在是一种糟糕的做法?
编辑:经过进一步调查,我发现了这些文章 http://www.hanselman.com/blog/AvoidUsingImpersonationInASPNET.aspx http://blog.codeishard.net/2012/09/17/await-async-mvc-and-impersonation/
除非有人告诉我其他情况,否则使用模拟似乎不是个好主意。
集成管道模式不再支持模拟。尤其是在使用异步方法时。
原因是 Impersonation 发生在线程上,当你调用一个异步函数时,它可能实际上在不同的线程上执行或return。
您应该使用 WindowsImpersonationContext 来包装您的数据库调用。
using System.Security.Principal;
...
//Get the identity of the current user
IIdentity contextId = HttpContext.Current.User.Identity;
WindowsIdentity userId = (WindowsIdentity)contextId;
//Temporarily impersonate
using (WindowsImpersonationContext imp = userId.Impersonate())
{
//Perform tasks using the caller's security context
DoSecuritySensitiveTasks();
}
确保在 using 块中执行此操作,因为如果代码中出现未捕获的异常,您最终将无法恢复原始上下文,并产生安全问题。
我最后的解决方案是在应用程序池中设置用户,而不是使用模拟。 这似乎与在具有同等安全性的 Web.config 中设置模拟具有完全相同的效果,只是在使用 Async 时没有问题。
正如@Erik 在他的回答中所说,似乎不再支持模拟,并且根据 http://www.hanselman.com/blog/AvoidUsingImpersonationInASPNET.aspx 它从来没有被鼓励放在首位。