DBA有给分配域账号权限(此示例中举例用户名是user,域是domain,密码是password),但是在EF中通过域账号访问数据库每次都不能访问,提示域账号未授权,但是如果一步步的调试代码结果又是正常的,难道哪里有异步代码?没看到。不太清楚具体原因,以下附上相关代码,请大家帮忙解决
连接字符串:
<add name="test" connectionString="metadata=res://*/Models.BaseTypeContext.csdl|res://*/Models.BaseTypeContext.ssdl|res://*/Models.BaseTypeContext.msl;provider=System.Data.SqlClient;provider connection string="data source=test;initial catalog=test;integrated security=SSPI;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
dbContext:
public BaseTypeContext()
: base("name=test")
{
Impersionate impersionate = Impersionate.Create("user", "domain", "password");
impersionate.Open();
}
其中蓝色部分代码如下,是为了每次初始化dbcontext的时候切换当前服务器机器的域以便访问数据库,具体实现部分如下:
public class Impersionate : IDisposable
{
public static int LOGON32_LOGON_INTERACTIVE = 2;
public static int LOGON32_PROVIDER_DEFAULT = 0;
public static int LOGON_TYPE_NEW_CREDENTIALS = 9;
public static int LOGON32_PROVIDER_WINNT50 = 3;
private WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
private extern static int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
public string User { get; protected set; }
public string Domain { get; protected set; }
protected string Password { get; set; }
protected bool Running { get; set; }
private Impersionate() { }
public static Impersionate Create(string user, string domain, string password)
{
Impersionate instance = new Impersionate();
instance.User = user;
instance.Domain = domain;
instance.Password = password;
instance.Running = false;
return instance;
}
public bool Open()
{
if (Running)
return Running;
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
int ret = LogonUser(User, Domain, Password, LOGON_TYPE_NEW_CREDENTIALS,
LOGON32_PROVIDER_WINNT50, ref token);
//int ret = LogonUser(User, Domain, Password, LOGON32_LOGON_INTERACTIVE,
//LOGON32_PROVIDER_DEFAULT, ref token);
if (ret != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
Running = true;
return Running;
}
else
{
Running = false;
throw new Exception(string.Format("Impersonate error code={0}", ret));
}
}
else
{
Running = false;
throw new Exception(string.Format("Impersonate error code={0}", ret));
}
}
else
{
Running = false;
throw new Exception(string.Format("Impersonate error code={0}", ret));
}
}
public void Close()
{
if (!Running)
return;
impersonationContext.Undo();
Running = false;
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
protected virtual void Dispose(bool disposing)
{
if (disposing && Running)
Close();
}
}
通过在IIS缓冲池配置该域账号就可以了.