Полномочия файла с FileSystemObject - в CScript.exe говорится одна вещь, Классик, ASP говорит другого

У меня есть классическая ASP-страница - записанный в JScript - это использует Сценарии. FileSystemObject, чтобы сохранить файлы к сетевому ресурсу - и это не работает. ("Разрешение, отклоненное")

ASP-страница работает под IIS с помощью аутентификации Windows с включенным олицетворением.

Если я выполняю следующий блок кода локально с помощью CScript.exe:

var objNet = new ActiveXObject("WScript.Network");
WScript.Echo(objNet.ComputerName);
WScript.Echo(objNet.UserName);
WScript.Echo(objNet.UserDomain);

var fso = new ActiveXObject("Scripting.FileSystemObject");
var path = "\\\\myserver\\my_share\\some_path";
if (fso.FolderExists(path)) {
    WScript.Echo("Yes");
} else {
    WScript.Echo("No");
}

Я получаю (ожидаемый) вывод:

MY_COMPUTER
dylan.beattie
MYDOMAIN
Yes

Если я выполняю тот же код как часть.ASP страницы, заменяя Ответом. Запишите для WScript. Эхо я получаю этот вывод:

MY_COMPUTER
dylan.beattie
MYDOMAIN
No

Теперь - мое понимание то, что WScript. Сетевой объект получит текущие учетные данные безопасности потока, это на самом деле выполняет код. Если это корректно - затем, почему тот же пользователь, на том же домене, получая различные результаты CScript.exe по сравнению с ASP? Если мой код ASP работает как dylan.beattie, то, почему я не могу видеть сетевой ресурс? И если это не работает как dylan.beattie, почему делает WScript. Сеть думает, что это?

6
задан Dylan Beattie 7 May 2010 в 19:19
поделиться

2 ответа

Ваша проблема ясна. В текущей реализации у вас есть только олицетворение пользователей, а не делегирование. Я не хочу повторять информацию, уже написанную Стивеном Мартином. Я хочу добавить как минимум три решения. Классический способ делегирования, который предлагает Стивен Мартин, - это только один способ. Вы можете прочитать еще несколько способов здесь: http://msdn.microsoft.com/en-us/library/ff647404.aspx#paght000023_delegation . Я вижу три практических способа решения вашей проблемы:

  1. Преобразование токена олицетворения пользователя в токен с уровнем делегирования олицетворения или в новый первичный токен. Это можно сделать в отношении DuplicateToken или DuplicateTokenEx .

  2. Используйте S4U2Self (см. http://msdn.microsoft.com/en-us/magazine/cc188757.aspx и http://msdn.microsoft. com / en-us / library / ms998355.aspx ), чтобы получить новый токен из старого с учетом одного простого оператора .NET WindowsIdentity wi = new WindowsIdentity (identity);

  3. Вы можете получить доступ другой сервер в отношении одной фиксированной учетной записи. Это может быть учетная запись компьютера в учетной записи пула приложений IIS. Это может быть другая фиксированная учетная запись, которая будет использоваться только для доступа к файловой системе.

Важно знать, какая версия Windows Server у вас установлена ​​на сервере, где работает IIS, и какой уровень функций домена у вас в Active Directory для вашего домена (вы увидите это в инструменте «Active Directory Domain and Trusts», если вы выберите свой домен и выберите «Повысить функциональный уровень домена»).Также интересно узнать, под какой учетной записью работает пул приложений IIS.

Первый и третий способы работают всегда. Третий способ может быть плохим для вашей среды и для текущего разрешения в файловой системе. Второй очень элегантен. Он позволяет контролировать, к каким серверам (файловым серверам) осуществляется доступ из IIS. Этот способ имеет некоторые ограничения и требует некоторой работы в Active Directory.

Поскольку вы используете классический ASP, необходимо создать небольшой программный компонент с поддержкой сценариев для поддержки вашей реализации.

Какой способ вы предпочитаете?

ОБНОВЛЕНО на основе вопроса из комментария: Поскольку вы используете классический ASP, вы не можете напрямую использовать Win32 API, но вы можете написать небольшой COM-компонент на VB6 или в. NET, которые используют нужные вам API. В качестве примера можно использовать код из http://support.microsoft.com/kb/248187/en . Но вы должны делать другие вещи внутри. Итак, теперь я объясню, какой Win32 API может помочь вам делать все, что вам нужно, с токенами и олицетворением.

Прежде всего, небольшое пояснение по поводу выдачи себя за другое лицо. Все работает очень просто. Всегда есть один первичный токен, под которым выполняется процесс. Любому потоку может быть назначен другой токен (токен потока). Для этого необходимо иметь токен пользователя hUserToken и вызывать API ImpersonateLoggedOnUser (hUserToken); .

Чтобы вернуться к исходному токену процесса (только для текущего потока), вы можете вызвать функцию RevertToSelf () .Токен пользователя будет получен и уже выдан за вас IIS, потому что вы так настроили свой веб-сайт. Чтобы вернуться к исходному токену процесса, вы должны реализовать вызов функции RevertToSelf () в вашем пользовательском COM-компоненте. Возможно, если вам не нужно больше ничего делать на странице ASP, этого будет достаточно, но я рекомендую вам быть внимательнее и сохранить токен текущего пользователя в переменной перед работой с файлами. Затем вы производите все операции с файловой системой и в конце переназначаете токен пользователя обратно текущему потоку. Вы можете назначить токен олицетворения потоку относительно SetThreadToken (NULL, hUserToken); . Чтобы предоставить (сохранить) токен текущего потока (токен пользователя в вашем случае), вы можете использовать OpenThreadToken API. Это должно сработать.

ОБНОВЛЕНО 2: Возможно, вам подойдет использование RevertToSelf () функции в конце одной страницы ASP. Соответствующий код C # может быть таким:

Создайте новый проект на C # типа «Библиотека классов» с именем LoginAdmin . Вставьте следующий код в

using System;
using System.Runtime.InteropServices;

namespace LoginAdmin {
    [InterfaceTypeAttribute (ComInterfaceType.InterfaceIsDual)]
    public interface IUserImpersonate {
        [DispId(1)]
        bool RevertToSelf ();
    }

    internal static class NativeMethods {
        [DllImport ("advapi32.dll", SetLastError = true)]
        internal static extern bool RevertToSelf ();
    }

    [ClassInterface (ClassInterfaceType.AutoDual)]
    public class UserImpersonate : IUserImpersonate {
        public UserImpersonate () { }

        public bool RevertToSelf () {
            return NativeMethods.RevertToSelf();
        }
    }
}

Проверьте свойства проекта в разделе «Сборка» «Регистрация для COM-взаимодействия». В части проекта «Подписание» установите флажок «Подписать сборку» и в поле «Выбрать файл ключа строгого имени» выберите <Создать ...> , затем введите любое имя файла и пароль (или установите флажок «Защитить мой ключ» ... "). В конце вы должны изменить строку из AssemblyInfo.cs в разделе «Свойства» проекта:

[assembly: ComVisible (true)]

После компиляции этого проекта вы получите два файла: LoginAdmin.dll и LoginAdmin.tlb.DLL уже зарегистрирована на текущем компьютере. Для регистрации на другом компьютере используйте RegAsm.exe .

Чтобы протестировать эту COM-DLL на странице ASP, выполните следующие действия.

<%@ Language="javascript" %>
<html><body>
    <% var objNet = Server.CreateObject("WScript.Network");
       Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
       Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");

       var objLoginAdmin = Server.CreateObject("LoginAdmin.UserImpersonate");
       var isOK = objLoginAdmin.RevertToSelf();
       if (isOK)
              Response.Write("RevertToSelf return true<br/>");
       else
              Response.Write("RevertToSelf return false<br/>");
       Response.Write("One more time after RevertToSelf()<br/>");
       Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
       Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");

       var fso = Server.CreateObject("Scripting.FileSystemObject");
       var path = "\\\\mk01\\C\\Oleg";
       if (fso.FolderExists(path)) {
          Response.Write("Yes");
       } else {
          Response.Write("No");
       }%>
</body></html>

Если учетная запись, используемая для запуска пула приложений IIS, имеет доступ к соответствующему сетевому ресурсу, результат будет выглядеть следующим образом

Current user: Oleg
Current user's domain: WORKGROUP
RevertToSelf return true
One more time after RevertToSelf()
Current user: DefaultAppPool
Current user's domain: WORKGROUP
Yes 
4
ответ дан 16 December 2019 в 21:36
поделиться

Под олицетворением вы можете получить доступ только к защищаемым ресурсам на локальном компьютере, вы не можете получить доступ ни к чему по сети.

В Windows, когда вы работаете как олицетворенный пользователь, вы работаете с так называемым сетевым токеном.Этот токен имеет учетные данные пользователя для доступа к локальному компьютеру, но не имеет учетных данных для удаленного доступа. Таким образом, когда вы получаете доступ к общему сетевому ресурсу, вы фактически получаете доступ к нему как анонимный пользователь.

Когда вы запускаете процесс на своем рабочем столе (например, CScript.exe), вы работаете с токеном интерактивного пользователя. Этот токен имеет полные учетные данные как для локального, так и для удаленного доступа, поэтому вы можете получить доступ к общему сетевому ресурсу.

Чтобы получить доступ к удаленным ресурсам при олицетворении пользователя Windows, вы должны использовать делегирование, а не олицетворение. Это повлечет за собой некоторые изменения в вашем Active Directory, чтобы разрешить делегирование для компьютера и / или пользователей в вашем домене. Это может быть угрозой безопасности, поэтому его следует тщательно изучить.

4
ответ дан 16 December 2019 в 21:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: