Рекомендации по аутентификации файлового потока SQL - PullRequest
4 голосов
/ 15 декабря 2010

Я смог нормально использовать поток файлов SQL локально, но когда я пытаюсь загрузить файлы на удаленный сервер SQL, который использует аутентификацию SQL, я получаю исключение «Отказ в доступе». Очевидно, что SQL Filestream работает только с аутентификацией Windows (Integrated Security = true), а не с аутентификацией SQL, которая у нас сейчас есть.

Никто на самом деле не использует проверку подлинности Windows в производственной среде, поэтому я просто хочу знать, как преодолеть это ограничение. Какая лучшая практика?

    public static void AddItem(RepositoryFile repository, byte[] data)
{
    using (var scope = new TransactionScope())
    {
        using (var db = new MyEntities()) // DBContext
        {
            db.RepositoryTable.AddObject(repository);
            db.SaveChanges();
        }

        using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
        using (var cmd = new SqlCommand(string.Format("SELECT Data.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT() FROM dbo.RepositoryTable WHERE ID='{0}'", repository.ID), con)) // "Data" is the column name which has the FILESTREAM. Data.PathName() gives me the local path to the file.
        {
            cmd.Connection.Open();
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    var path = reader.GetString(0);
                    var transactionContext = reader.GetSqlBytes(1).Buffer;
                    var fileStream = new SqlFileStream(path, transactionContext, FileAccess.Write);

                    fileStream.Write(contents, 0, contents.Length); // I get the error at this line.
                    fileStream.Close();
                }
            }
        }

        scope.Complete();
    }
}

Ответы [ 2 ]

4 голосов
/ 15 декабря 2010

Вы действительно должны использовать встроенную аутентификацию при использовании FILESTREAM:

Хранилище FILESTREAM в SQL Server 2008

Вам необходимо убедиться, что учетная запись Windows, которая используется для производстваприложение, под которым выполняется приложение, было добавлено в качестве имени входа в SQL Server, и ему были предоставлены те же разрешения, что и для учетной записи аутентификации SQL, используемой в настоящее время приложением.

Необходимо также убедиться, что у учетной записи есть разрешения файловой системы для записи вКонтейнер FILESTREAM.

3 голосов
/ 01 июня 2012

Я получал похожее сообщение «Отказано в доступе» на примере SqlFileStream.Это поставило нас в тупик на несколько дней.

Коллега предложил альтернативный подход, который прекрасно работал.Вместо использования SqlFileStream запишите байты файла непосредственно на сервер SQL с помощью команды INSERT с аргументом, который принимает значение в байтах.Для нашей таблицы «FileData» со столбцами «Id» (guid) и «Bytes» я бы использовал что-то вроде этого:

Byte[] bytes = // assign your data here

using (SqlConnection conn = new SqlConnection(connectionString)) {
    SqlCommand insertCmd = new SqlCommand("INSERT INTO FileData (Id, Bytes) VALUES (@Id, @Bytes)", conn);

    insertCmd.CommandType = System.Data.CommandType.Text;
    insertCmd.Parameters.AddWithValue("@Id", Guid.NewGuid());
    insertCmd.Parameters.AddWithValue("@Bytes", bytes);
    insertCmd.Transaction = conn.BeginTransaction();

    try {
        insertCmd.ExecuteNonQuery();
        insertCmd.Commit();
    }
    catch (Exception e) {
        insertCmd.Transaction.Rollback();
    }
}

Обратите внимание, что класс SqlFileStream НЕ используется.

...