2011-01-11 40 views
1

ファイルシステムにファイルを保存するためにSQL SERVER 2008 Filestreamと偽装テクニックを使用してファイルをデータベースにアップロードしようとしましたが、アクセス拒否エラーが発生します。 Filestreamフォルダ(C:\ SQLFILESTREAM \ Dev_DB)への偽装ユーザーのアクセス許可を設定しています。私はコードをデバッグしたとき、私はサーバーがWindowsエクスプローラからアクセスできないuncパス(\ Server_Name \ MSSQLSERVER \ v1 \ Dev_LMDB \ dbo \ FileData \ File_Data \ 13C39AB1-8B91-4F5A-81A1-940B58504C17)を返すことを発見しました。 私は自分のウェブアプリケーションをローカルマシンでホストしています(Windows 7)。 SQL Serverはリモートサーバー(Windows Server 2008 R2)にあります。ストアドプロシージャを呼び出すためにSQL認証が使用されました。SQL Server 2008 Filestream偽装アクセスが拒否されたエラー

以下は、上記の操作を行うために使用したコードです。

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) 

おかげ

答えて

2

SQL認証は、ファイルストリームデータ

FILESTREAM Storage in SQL Server 2008

+0

統合セキュリティでユーザーを偽装することで問題が解決しました。 http://social.msdn.microsoft.com/Forums/en-US/sqlnetfx/thread/157971a4-335f-4138-bdf8-89d0a20f0031 ありがとう – Adi

0

LOGON32_LOGON_INTERACTIVEではなくLOGON32_LOGON_NETWORKを使用してみてください。私は何年も前にUNC偽装のAPI呼び出しを使用してこのエラーに遭遇しました。

+0

ChrisさんがLOGON32_LOGON_NETWORKに変更しても、私にとってはうまくいかなかったのです。例外の詳細とuncパスを追加しました。返信いただきありがとうございます。 – Adi

+0

これは、プロセスがセキュリティトークンを提示しており、システムがトークンをACLと比較していて見つからないという本質的な性質です。 –

+0

ここで役に立つのは、TARGETサーバー上でProcess Monitorを実行し、アクセス拒否エントリの詳細を探すことです。プロセスが私たちが期待しているアイデンティティを持っていない可能性があると私は思っています。プロセスモニタはhttp://technet.microsoft.com/en-us/sysinternals/bb896645にあります。 –

0

にアクセスしたときに、私は同じ問題を抱えていたサポートされていません。解決策は、SQL Server Configuration Managerの[FileStream]タブにあるすべてのチェックボックスをチェックすることでした。 http://msdn.microsoft.com/en-us/library/cc645923(v=sql.100).aspx

注意点7と8:ここで

は、MSDN上の命令であり、あなたが読んでとWindowsからFILESTREAMデータを書き込みたい場合は

  1. 、ファイルに対してFILESTREAMを有効にする]をクリックしますI/Oストリーミングアクセス。 [Windows共有名]ボックスに Windows共有の名前を入力します。
  2. この共有に格納されているFILESTREAMデータにリモートクライアントがアクセスする必要がある場合は、リモートクライアントに FILESTREAMデータへのストリーミングアクセスを許可するを選択します。

従って、我々は、我々は、エラーの原因となった、すべてのチェックボックスを有効にし、もともと我々は最初の3つのみを確認し必要なファイルのストリームにアクセスするリモートクライアントを持っていました。

関連する問題