Проблемы с имитацией .NET и загрузкой файлов - PullRequest
3 голосов
/ 30 марта 2010

У меня есть веб-страница, которая позволяет пользователю загружать файл в общий сетевой ресурс. Когда я запускаю веб-страницу локально (в VS 2008) и пытаюсь загрузить файл, это работает ! Однако когда я развертываю веб-сайт на веб-сервере и пытаюсь загрузить файл через веб-страницу, он не работает !

Ошибка, возвращаемая мне на веб-сервере, гласит: «Доступ к пути« \ 05prd1 \ emp \ test.txt »запрещен. Поэтому, очевидно, это проблема с разрешениями.

Сетевой ресурс настроен так, чтобы разрешить полный доступ как ко мне (проверка подлинности NT), так и к СЕТИ СЕТИ (которая является учетной записью .NET по умолчанию и которую мы указали в нашем пуле приложений IIS в качестве пользователя по умолчанию для этого веб-сайта).

Я пробовал это с и без олицетворения на веб-сервере, и ни один из способов не работает, все же оба способа работают на моей локальной машине (другими словами, с и без олицетворения работает на моей локальной машине).

Код загрузки файла приведен ниже. Обратите внимание, что приведенный ниже код включает в себя олицетворение, но, как я уже говорил выше, я пробовал его с олицетворением и без него, и это не имело никакого значения.

if (fuCourses.PostedFile != null && fuCourses.PostedFile.ContentLength > 0) {
    System.Security.Principal.WindowsImpersonationContext impCtx;
    impCtx =
        ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

    try {
        lblMsg.Visible = true;

        // The courses file to be uploaded
        HttpPostedFile file = fuCourses.PostedFile;
        string fName = file.FileName;
        string uploadPath = "\\\\05prd1\\emp\\";

        // Get the file name
        if (fName.Contains("\\")) {
            fName = fName.Substring(
                fName.LastIndexOf("\\") + 1);
        }

        // Delete the courses file if it is already on \\05prd1\emp
        FileInfo fi = new FileInfo(uploadPath + fName);
        if (fi != null && fi.Exists) {
            fi.Delete();
        }

        // Open new file stream on \\05prd1\emp and read bytes into it from file upload
        FileStream fs = File.Create(uploadPath + fName, file.ContentLength);

        using (Stream stream = file.InputStream) {
            byte[] b = new byte[4096];
            int read;

            while ((read = stream.Read(b, 0, b.Length)) > 0) {
                fs.Write(b, 0, read);
            }
        }

        fs.Close();

        lblMsg.Text = "File Successfully Uploaded";
        lblMsg.ForeColor = System.Drawing.Color.Green;
    }
    catch (Exception ex) {
        lblMsg.Text = ex.Message;
        lblMsg.ForeColor = System.Drawing.Color.Red;
    }
    finally {
        impCtx.Undo();
    }
}

Любая помощь по этому вопросу будет очень признателен!

Ответы [ 2 ]

1 голос
/ 01 апреля 2010

Проблема заключается в том, что Kerberos не делегируется с веб-сервера на файловый сервер. Идеальным решением было бы делегировать Kerberos файловому серверу. К сожалению, это не то, что я могу изменить. Слишком много волокиты и политики. Тем не менее, я придумал что-то вроде взлома.

Я создал временную папку, расположенную в корне сайта. Используя олицетворение, я записываю файл в эту временную папку (другими словами, он загружается в эту временную папку).

Записав файл во временную папку, я затем скопирую файл на файловый сервер UNC. Это второй переход, и здесь нет разницы, использую ли я олицетворение или нет - потому что учетные данные, отправляемые на файловый сервер, принадлежат самому веб-серверу. Итак, это заставило меня предоставить доступ на чтение / запись к веб-серверу на общем ресурсе UNC. После всего этого копия файла работала как положено.

1 голос
/ 01 апреля 2010

Вы не упоминаете, какую аутентификацию вы используете в IIS.

Если вы полагаетесь на встроенную аутентификацию Windows / NTLM, то, я думаю, у вас возникнет проблема в том, что, если вы не сможете настроить Kerberos на своих серверах, маркер аутентификации пользователя не может использоваться за пределами текущего (веб) сервера - Проблема " double-hop ".

Если вы используете Basic (в IIS) или Forms (через ASP.NET), то у вас будет доступ к паролю пользователя в виде открытого текста. Затем вы можете вызвать код олицетворения, используя имя пользователя / пароль, и сможете получить доступ к общей папке как этот пользователь.

Я также уверен, что если вы используете обычную аутентификацию, то тег будет работать для доступа к сетевому ресурсу.

Проверьте KB 306158 для получения дополнительной информации и примеров кода.

...