在多租户环境中使用SQL身份验证实现FileStream

时间:2019-09-09 23:50:34

标签: c# sql-server filestream filetable sqlfilestream

我们需要使用SQL登录名(在多租户环境中每个数据库通常使用一个SQL登录名)登录SQL Server,但是我们需要在C#中使用sqlFileStream类使用文件流功能。

目前的方法,但实施起来非常复杂:

在应用程序代码中,为文件流所需的每个相关sql命令动态添加EXECUTE AS [Service Account]。(由于应用程序通过SQL身份验证进行连接,因此文件流需要Windows用户获取文件和事务上下文的逻辑路径)

例如

sqlCommand3.CommandText = @"
  execute as login ='Domain\xxxxxxx';
  Select
    FileData.PathName() As Path,
    GET_FILESTREAM_TRANSACTION_CONTEXT() As TransactionContext
  From PictureTable
  Where PkId = (Select Max(PkId) From PictureTable)";

在数据库级别,我们需要将Active Directory组(其中包含所有服务帐户)添加为SQL登录名,并且还需要在每个数据库中添加为用户

我们还需要在实例级别将每个服务帐户创建为SQL登录。

我们需要模拟每个服务帐户登录名给每个数据库用户(每个数据库一个用户)

例如GRANT IMPERSONATE on LOGIN::[Domain\xxxxxxx] to APPUSER;

using (TransactionScope transactionScope = new TransactionScope())
{
    SqlConnection sqlConnection1 = new SqlConnection("Data Source=xxxxx-xxxxx;Initial Catalog=xxxxx;User ID=xxxx;Password=xxxx");
    SqlCommand sqlCommand1 = sqlConnection1.CreateCommand();
    sqlCommand1.CommandText = @"execute as login ='XXXXXX\XXXXXX';Insert Into PictureTable(Description,FileData) values('" + Guid.NewGuid().ToString() + "',Cast('' As varbinary(Max))); Select FileData.PathName() As Path From PictureTable Where PkId =@@Identity";

    sqlConnection1.Open();

    string filePath1 = (string)sqlCommand1.ExecuteScalar();

    SqlConnection sqlConnection2 = new SqlConnection("Data Source=xxxxx-xxxxx;Initial Catalog=xxxxx;User ID=xxxx;Password=xxxx");
    SqlCommand sqlCommand2 = sqlConnection2.CreateCommand();
    sqlCommand2.CommandText = @"execute as login ='XXXXXX\XXXXXX';Select  GET_FILESTREAM_TRANSACTION_CONTEXT() As TransactionContext";
    sqlConnection2.Open();
    byte[] transactionContext1 = (byte[])sqlCommand2.ExecuteScalar();

    SqlFileStream sqlFileStream1 = new SqlFileStream(filePath1, transactionContext1, FileAccess.Write);
    byte[] fileData = Guid.NewGuid().ToByteArray();
    sqlFileStream1.Write(fileData, 0, fileData.Length);
    sqlFileStream1.Close();
    transactionScope.Complete();
}

0 个答案:

没有答案