ASP.Net Identity失去模仿

时间:2015-06-26 16:32:54

标签: c# asp.net async-await impersonation asp.net-identity-2

我遇到很多问题,每当我调用ASP.Net Identity异步方法时,我都会从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/

看起来好像使用假冒是一个坏主意,除非有人能告诉我。

2 个答案:

答案 0 :(得分:2)

Integrated Pipeline模式不再支持模拟。特别是在使用异步方法时。

原因是模拟发生在线程上,当你调用异步函数时,它实际上可能在另一个线程上执行或返回。

您应该使用WindowsImpersonationContext来包装数据库调用。

https://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext(v=vs.110).aspx

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块中执行此操作,因为如果代码中发生未捕获的异常,您最终将无法恢复原始上下文,并且会产生安全问题。

答案 1 :(得分:0)

我的解决方案最终是将用户设置在App Pool而不是使用模拟。 这似乎与在Web.config中设置具有同等安全性的模拟完全相同,只是没有使用Async时的问题。

正如@Erik在他的回答中所说,根据http://www.hanselman.com/blog/AvoidUsingImpersonationInASPNET.aspx,似乎不再支持假冒 从一开始就没有鼓励过。