SQL Server 2008 文件流模拟访问被拒绝错误
Posted
技术标签:
【中文标题】SQL Server 2008 文件流模拟访问被拒绝错误【英文标题】:SQL Server 2008 Filestream Impersonation Access Denied error 【发布时间】:2011-01-11 17:45:10 【问题描述】:我一直在尝试使用 SQL SERVER 2008 文件流和模拟技术将文件上传到数据库以将文件保存在文件系统中,但我不断收到拒绝访问错误;即使我已将模拟用户的权限设置为 Filestream 文件夹(C:\SQLFILESTREAM\Dev_DB)。当我调试代码时,我发现服务器返回了一个无法通过 Windows 资源管理器访问的 unc 路径(\Server_Name\MSSQLSERVER\v1\Dev_LMDB\dbo\FileData\File_Data\13C39AB1-8B91-4F5A-81A1-940B58504C17)。 我的 Web 应用程序托管在本地 Macing(Windows 7)上。 SQL Server 位于远程服务器 (Windows Server 2008 R2) 上。调用存储过程使用了Sql认证。
以下是我用来执行上述操作的代码。
SqlCommand sqlCmd = new SqlCommand("AddFile");
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.Add("@File_Name", SqlDbType.VarChar, 512).Value = filename;
sqlCmd.Parameters.Add("@File_Type", SqlDbType.VarChar, 5).Value = Path.GetExtension(filename);
sqlCmd.Parameters.Add("@Username", SqlDbType.VarChar, 20).Value = username;
sqlCmd.Parameters.Add("@Output_File_Path", SqlDbType.VarChar, -1).Direction = ParameterDirection.Output;
DAManager PDAM = new DAManager(DAManager.getConnectionString());
using (SqlConnection connection = (SqlConnection)PDAM.CreateConnection())
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();
WindowsImpersonationContext wImpersonationCtx;
NetworkSecurity ns = null;
try
PDAM.ExecuteNonQuery(sqlCmd, transaction);
string filepath = sqlCmd.Parameters["@Output_File_Path"].Value.ToString();
sqlCmd = new SqlCommand("SELECT GET_FILESTREAM_TRANSACTION_CONTEXT()");
sqlCmd.CommandType = CommandType.Text;
byte[] Context = (byte[])PDAM.ExecuteScalar(sqlCmd, transaction);
byte[] buffer = new byte[4096];
int bytedRead;
ns = new NetworkSecurity();
wImpersonationCtx = ns.ImpersonateUser(IMP_Domain, IMP_Username, IMP_Password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT);
SqlFileStream sfs = new SqlFileStream(filepath, Context, System.IO.FileAccess.Write);
while ((bytedRead = inFS.Read(buffer, 0, buffer.Length)) != 0)
sfs.Write(buffer, 0, bytedRead);
sfs.Close();
transaction.Commit();
catch (Exception ex)
transaction.Rollback();
finally
sqlCmd.Dispose();
connection.Close();
connection.Dispose();
ns.undoImpersonation();
wImpersonationCtx = null;
ns = null;
谁能帮我解决这个问题。 Reference
Exception:
Type : System.ComponentModel.Win32Exception, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Message : Access is denied Source : System.Data Help link :
NativeErrorCode : 5
ErrorCode : -2147467259
Data : System.Collections.ListDictionaryInternal
TargetSite : Void OpenSqlFileStream(System.String, Byte[], System.IO.FileAccess, System.IO.FileOptions, Int64)
Stack Trace : at System.Data.SqlTypes.SqlFileStream.OpenSqlFileStream(String path, Byte[] transactionContext, FileAccess access, FileOptions options, Int64 allocationSize)
at System.Data.SqlTypes.SqlFileStream..ctor(String path, Byte[] transactionContext, FileAccess access, FileOptions options, Int64 allocationSize)
at System.Data.SqlTypes.SqlFileStream..ctor(String path, Byte[] transactionContext, FileAccess access)
谢谢
【问题讨论】:
【参考方案1】:访问Filestream数据时不支持Sql认证
FILESTREAM Storage in SQL Server 2008
【讨论】:
模拟具有集成安全性的用户解决了该问题。 social.msdn.microsoft.com/Forums/en-US/sqlnetfx/thread/…谢谢【参考方案2】:尝试使用 LOGON32_LOGON_NETWORK 而不是 LOGON32_LOGON_INTERACTIVE。多年前我在使用 API 调用进行 UNC 模拟时遇到了这个错误,所以它可能仍然存在。
【讨论】:
克里斯,将其更改为 LOGON32_LOGON_NETWORK 对我不起作用。我添加了异常详细信息和 unc 路径。感谢您的回复。 因此,本质上是您的进程提供了一个安全令牌,而系统正在将该令牌与 ACL 进行比较,但没有找到它。 这里可能有帮助的是在目标服务器上运行进程监视器,并查找拒绝访问条目的详细信息;我怀疑这个过程可能没有我们期望的身份。进程监视器可以在这里找到:technet.microsoft.com/en-us/sysinternals/bb896645.【参考方案3】:我遇到了同样的问题。解决方案是选中 SQL Server 配置管理器的“FileStream”选项卡上的所有复选框。
以下是 MSDN 上的说明: http://msdn.microsoft.com/en-us/library/cc645923(v=sql.100).aspx
注意第 7 点和第 8 点:
如果要从 Windows 读取和写入 FILESTREAM 数据,请单击启用 FILESTREAM 以进行文件 I/O 流式访问。输入名称 Windows 共享名称框中的 Windows 共享。 如果远程客户端必须访问存储在此共享上的 FILESTREAM 数据,请选择允许远程客户端具有流式访问 FILESTREAM 数据。
我们有远程客户端访问文件流,因此我们需要启用所有复选框,而最初我们只检查了前三个,这导致了错误。
【讨论】:
以上是关于SQL Server 2008 文件流模拟访问被拒绝错误的主要内容,如果未能解决你的问题,请参考以下文章
怎样通过计算机ip地址访问sql server 2008数据库
2个sql server 2008 r2服务器相互访问对方的实例