我遇到很多问题,每当我调用ASP.Net Identity Async方法时,我都会从SQL服务器获得访问被拒绝的异常.
以下内容返回用户:
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配置/ system.web部分中有以下行
<identity impersonate="true" userName="DOMAIN\Domain User" password="xxx" />
此模拟用户有权访问SQL Server数据库,但应用程序池用户没有.似乎每当我在ASP.Net Identity中调用异步方法时,它都会回退到app pool用户并失去模拟.
我确实找到了一个类似的问题,在这里有一个解释https://stackoverflow.com/a/30876110/1093406
这也可能导致我的问题吗?
除了将应用程序池用户更改为具有数据库访问权限的用户之外,还有什么方法吗?
是否正在使用web.config将模拟用户设置为旧的处理方式,现在是不好的做法?
编辑:经过进一步调查后,我发现了这些文章
http://www.hanselman.com/blog/AvoidUsingImpersonationInASPNET.aspx
http://blog.codeishard.net/2012/09/17/await-async-mvc-and-impersonation/
看起来好像使用模仿是个坏主意,除非有人能告诉我.
最佳答案 集成管道模式不再支持模拟.特别是在使用异步方法时.
原因是模拟发生在线程上,当你调用异步函数时,它实际上可能在不同的线程上执行或返回.
您应该使用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块中执行此操作,因为如果代码中发生未捕获的异常,您最终将无法恢复原始上下文,并且会产生安全问题.