Можно ли использовать провайдер setAcl Web Deploy в подкаталоге?

Я пытаюсь сделать подкаталог в пакете MS Deploy доступным для записи пользователю пула приложений. Благодаря полезному сообщению о поставщике setAcl от Kevin Leetham Я смог получить большую часть того, что мне нужно, в файл проекта:

<MsDeploySourceManifest Include="setAcl"
                        Condition="$(IncludeSetAclProviderOnDestination)">
  <Path>$(_MSDeployDirPath_FullPath)\doc\public</Path>
  <setAclAccess>Read,Write,Modify</setAclAccess>
  <setAclResourceType>Directory</setAclResourceType>
  <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
</MsDeploySourceManifest>

Обратите внимание, что я добавил "\doc\public" в корневой каталог развертывания. В результирующем манифесте, созданном VS2010, я вижу следующий элемент setAcl:

<sitemanifest>
  <contentPath path="C:\Source\...\obj\Debug\Package\PackageTmp" />
  <setAcl path="C:\Source\...\obj\Debug\Package\PackageTmp"
          setAclResourceType="Directory" />
  <setAcl path="C:\Source\...\obj\Debug\Package\PackageTmp"
          setAclUser="anonymousAuthenticationUser"
          setAclResourceType="Directory" />
  <setAcl path="C:\Source\...\obj\Debug\Package\PackageTmp\doc\public"
          setAclResourceType="Directory"
          setAclAccess="Read,Write,Modify" />
</sitemanifest>

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

Однако, когда я развертываю этот пакет, я получаю сообщение об ошибке:

Ошибка: значение параметра setAclUser должно быть указано, когда поставщик setAcl используется с физическим путем.

Это запутанная ошибка, потому что я пытаюсь установить ACL не на физический путь, а на подкаталог веб-приложения. Глядя на вывод MS Deploy, легко увидеть проблему:

Info: Adding setAcl (REST Services\1.0.334).
Info: Adding setAcl (REST Services\1.0.334).
Info: Adding setAcl (C:\...\obj\Release\Package\PackageTmp\doc\public).

MS Deploy, по-видимому, заменяет имя веб-приложения на мой абсолютный путь "C:...\obj\Release\Package\PackageTmp", но когда я добавляю "\doc\public" к этому абсолютному пути, он больше не распознает его как каталог веб-приложений. Эта точная проблема описана другой жертвой на Форумы ASP.NET без разрешения.

Кто-нибудь знает, как установить ACL для определенного подкаталога веб-приложения через веб-развертывание без ручной идентификации физического пути и пользователя пула приложений на целевом хосте?


person ladenedge    schedule 28.07.2011    source источник


Ответы (2)


Хорошо, позвольте мне сначала сказать, что это намного сложнее, чем должно быть!

Я думаю, что причина сбоя заключается в том, что при публикации он не может распознать папку как папку в приложении IIS. Это происходит потому, что полный путь передается в пункт назначения при вызове поставщика SetAcl. Вместо этого нам нужен путь, который относится к приложению IIS. Например, в вашем случае это должно быть что-то вроде: «REST SERVICES/1.0.334/doc/public». Единственный способ сделать это — создать параметр MSDeploy, который будет заполнен правильным значением во время публикации. Вам придется сделать это в дополнение к созданию собственной записи SetAcl в исходном манифесте. Следуйте инструкциям ниже.

  1. В том же каталоге, что и ваш проект, создайте файл с именем {ProjectName}.wpp.targets (где {ProjectName} — это имя вашего проекта веб-приложения).
  2. Внутри файла вставьте содержимое MSBuild, которое находится ниже этого списка.
  3. Перезагрузите проект в Visual Studio (VS кэширует файлы проекта в памяти, поэтому этот кеш необходимо очистить).

{ProjectName}.wpp.targets

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="SetupCustomAcls" AfterTargets="AddIisSettingAndFileContentsToSourceManifest">   
    <!-- This must be declared inside of a target because the property 
    $(_MSDeployDirPath_FullPath) will not be defined at that time. -->
    <ItemGroup>
      <MsDeploySourceManifest Include="setAcl">
        <Path>$(_MSDeployDirPath_FullPath)\doc\public</Path>
        <setAclAccess>Read,Write,Modify</setAclAccess>
        <setAclResourceType>Directory</setAclResourceType>
        <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
      </MsDeploySourceManifest>
    </ItemGroup>
  </Target>

  <Target Name="DeclareCustomParameters" AfterTargets="AddIisAndContentDeclareParametersItems">
    <!-- This must be declared inside of a target because the property 
    $(_EscapeRegEx_MSDeployDirPath) will not be defined at that time. -->
    <ItemGroup>
      <MsDeployDeclareParameters Include="DocPublicSetAclParam">
        <Kind>ProviderPath</Kind>
        <Scope>setAcl</Scope>
        <Match>^$(_EscapeRegEx_MSDeployDirPath)\\doc\\public$</Match>
        <Value>$(_DestinationContentPath)/doc/public</Value>
        <ExcludeFromSetParameter>True</ExcludeFromSetParameter>
      </MsDeployDeclareParameters>
    </ItemGroup>
  </Target>

</Project>

Чтобы немного объяснить это, целевой SetupCustomAcls приведет к тому, что новая запись SetAcl будет помещена внутрь исходного манифеста, используемого во время публикации. Эта цель выполняется после выполнения цели AddIisSettingAndFileContentsToSourceManifest через атрибут AfterTargets. Мы делаем это, чтобы гарантировать, что значение элемента будет создано в нужное время, и потому что нам необходимо убедиться, что свойство _MSDeployDirPath_FullPath заполнено.

DeclareCustomParameters — это место, где будет создан настраиваемый параметр MSDeploy. Эта цель будет выполняться после цели AddIisAndContentDeclareParametersItems. Мы делаем это, чтобы убедиться, что свойство _EscapeRegEx_MSDeployDirPath заполнено. Обратите внимание, что внутри этой цели, когда я объявляю значение параметра (внутри элемента Value), я использую свойство _DestinationContentPath, которое является свойством MSBuild, содержащим путь к месту развертывания вашего приложения, т. е. Службы REST/1.0.334.

Можете ли вы попробовать это и сообщить мне, сработало ли это для вас или нет?

person Sayed Ibrahim Hashimi    schedule 29.07.2011
comment
Хех, мне совсем не жаль, что я не разобрался с этим сам. Тем не менее, это действительно работает, и я благодарен, что вы нашли время, чтобы создать такой исчерпывающий ответ! - person ladenedge; 29.07.2011
comment
Есть ли способ заставить это работать для нескольких папок? Например, как бы вы расширили это, чтобы сделать доступным для записи не только doc/public, но и /home/temp? - person TimH; 06.12.2011
comment
Вы должны иметь возможность просто скопировать значение элемента для MSDeploySourceManifest и MSDeployDeclareParameters и обновить значения. Вы пробовали это, и это не сработало - person Sayed Ibrahim Hashimi; 07.12.2011
comment
К сведению: похоже, это не работает для приложений, которые не помещаются в виртуальный каталог, а помещаются, например, на сайт по умолчанию/. Я пытаюсь понять, как настроить его, чтобы он работал и для этого сценария. Ошибка в строке 3847 Web.Publishing.targets, где вызывается VSMSDeploy — сайт не существует. - person Ethan J. Brown; 02.02.2012
comment
Это может быть ошибка, можете ли вы отправить мне подробности по электронной почте, чтобы я мог следить за этим? Мой адрес электронной почты sayedha [at]{Microsoft}dotCOM. - person Sayed Ibrahim Hashimi; 03.02.2012

К сведению: это работает для корневого веб-сайта, если вы следуете соглашению, указанному в сообщении здесь: http://forums.iis.net/p/1176955/1977169.aspx#1977169

<Match>^$(_EscapeRegEx_MSDeployDirPath)\\@(CustomDirAcl)$</Match>
<DefaultValue>{$(_MsDeployParameterNameForContentPath)}/@(CustomDirAcl)</DefaultValue>
<Value>$(_DestinationContentPath)/@(CustomDirAcl)</Value>

Этот пост также имеет то преимущество, что позволяет указать блок подкаталогов в одной ItemGroup.

person Ethan J. Brown    schedule 02.02.2012
comment
Использование использования DefaultValue для наследования значения существующего параметра делает этот ответ гораздо более предпочтительным. - person Richard Szalay; 10.10.2012