iis-7 - 通过 MSBuild 在 Web 部署期间设置 ACL

标签 iis-7 msbuild msdeploy msbuild-wpp

我有一个在 TeamCity 中运行的主要工作的 Web 构建和部署配置,它基本上使用 MSBuild 自动将站点部署到 Web 服务器。默认情况下,MSDeploy 将目标服务器上的所有内容都设置为只读,我需要 AppPool 身份才能对一个文件夹进行写访问。

我找到了 an article by Kevin leetham这让我完成了 90% 的工作。 Kevin 描述了如何通过创建一个名为 ProjectName.wpp.targets 的文件来连接到 MSBuild Web 发布管道,如下所示:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
     <!--Extends the AfterAddIisSettingAndFileContentsToSourceManifest action do also set ACLs -->

    <IncludeCustomACLs>TRUE</IncludeCustomACLs>

    <AfterAddIisSettingAndFileContentsToSourceManifest Condition="'$(AfterAddIisSettingAndFileContentsToSourceManifest)'==''">
      $(AfterAddIisSettingAndFileContentsToSourceManifest);
      SetCustomACLs;
    </AfterAddIisSettingAndFileContentsToSourceManifest>
  </PropertyGroup>
  <Target Name="SetCustomACLs" Condition="'$(IncludeCustomACLs)'=='TRUE'">
    <Message Text="Adding Custom ACls" />
    <ItemGroup>
      <!-- Ensure the AppPool identity has write access to the Files directory -->
      <MsDeploySourceManifest Include="setAcl" Condition="$(IncludeSetAclProviderOnDestination)">
        <Path>$(_MSDeployDirPath_FullPath)\files</Path>
        <setAclAccess>Read,Write,Modify</setAclAccess>
        <setAclResourceType>Directory</setAclResourceType>
        <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
      </MsDeploySourceManifest>
    </ItemGroup>
  </Target>
</Project>

这几乎是有效的,它让我发疯。 ACL 被添加到 list 中,但问题是它根据构建位置生成绝对路径,而不是相对于目标服务器上的 IIS Web 应用程序。生成的 list 是这样出来的(为了保护无辜者,一些名字已经改变了):
<?xml version="1.0" encoding="utf-8"?>
<sitemanifest>
  <IisApp path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" managedRuntimeVersion="v4.0" />
  <setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" setAclResourceType="Directory" />
  <setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" />
  <setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp\files" setAclResourceType="Directory" setAclAccess="Read,Write,Modify" />
</sitemanifest>

这实际上看起来是正确的,最后一行是我从 wpp.targets 文件中自定义的 ACL。但是,当 MSDeploy 将其发送到目标服务器时,会发生以下情况:

2>Start Web Deploy 将应用程序/包发布到 https://webhostingprovider.biz:8172/msdeploy.axd?site=IisWebAppName ...
2>添加站点 list (sitemanifest)。
2>为路径添加 ACL (IisWebAppName)
2>为路径添加 ACL (IisWebAppName)
2>为路径添加 ACL (C:\SolutionPath\IisWebAppname\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp\files)
2>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets(4377,5):错误 ERROR_USER_NOT_AUTHORIZED_FOR_SETACL:Web 部署任务失败。 (使用 Web 管理服务进行连接时,无法使用指定的提供程序(“setAcl”)完成操作。如果服务器管理员未授权用户执行此操作,则可能会发生这种情况。setAcl http://go.microsoft.com/fwlink/?LinkId=178034

整个事情都落在我的自定义 ACL 路径上,它使用绝对路径名而不是相对于 IisWebAppName。我想不通为什么!!

请帮忙 :)

最佳答案

您需要创建一个 ProviderPath带有 DefaultValue 的参数使用 {param name} 获取另一个参数的值句法。

这是我在 another question 上包含的一个助手执行所有操作:

<ItemDefinitionGroup>
  <AdditionalAcls>
    <AclAccess>Write</AclAccess>
    <ResourceType>Directory</ResourceType>
  </AdditionalAcls>
</ItemDefinitionGroup>

<PropertyGroup>
  <AfterAddIisSettingAndFileContentsToSourceManifest>
    $(AfterAddIisSettingAndFileContentsToSourceManifest);
    AddAdditionalAclsToSourceManifest;
  </AfterAddIisSettingAndFileContentsToSourceManifest>
  <AfterAddIisAndContentDeclareParametersItems>
    $(AfterAddIisAndContentDeclareParametersItems);
    AddAdditionalAclsDeclareParameterItems
  </AfterAddIisAndContentDeclareParametersItems>
</PropertyGroup>

<Target Name="AddAdditionalAclsToSourceManifest">
  <ItemGroup Condition="'@(AdditionalAcls)' != ''">
    <MsDeploySourceManifest Include="setAcl">
      <Path>$(_MSDeployDirPath_FullPath)\%(AdditionalAcls.Identity)</Path>
      <setAclResourceType Condition="'%(AdditionalAcls.ResourceType)' != ''">%(AdditionalAcls.ResourceType)</setAclResourceType>
      <setAclAccess>%(AdditionalAcls.AclAccess)</setAclAccess>
      <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
    </MsDeploySourceManifest>
  </ItemGroup>
</Target>

<Target Name="AddAdditionalAclsDeclareParameterItems">
  <ItemGroup Condition="'@(AdditionalAcls)' != ''">
    <MsDeployDeclareParameters Include="Add %(AdditionalAcls.AclAccess) permission to %(AdditionalAcls.Identity) Folder">
      <Kind>ProviderPath</Kind>
      <Scope>setAcl</Scope>
      <Match>^$(_EscapeRegEx_MSDeployDirPath)\\@(AdditionalAcls)$</Match>
      <Description>Add %(AdditionalAcls.AclAccess) permission to %(AdditionalAcls.Identity) Folder</Description>
      <DefaultValue>{$(_MsDeployParameterNameForContentPath)}/@(AdditionalAcls)</DefaultValue>
      <DestinationContentPath>$(_DestinationContentPath)/@(AdditionalAcls)</DestinationContentPath>
      <Tags>Hidden</Tags>
      <ExcludeFromSetParameter>True</ExcludeFromSetParameter>
      <Priority>$(VsSetAclPriority)</Priority>
    </MsDeployDeclareParameters>
  </ItemGroup>
</Target>

您可以通过声明来使用它:
<ItemGroup>
    <AdditionalAcls Include="MyRelativeWritableDirectory" />
</ItemGroup>

请注意 该解决方案目前仅在路径中不需要反斜杠时才有效(即,如果它只是根目录)。如果您需要一个子目录,则需要窃取我用于“SkipDeleteItems”(在该答案后面)的技巧,以将正则表达式转义的路径元数据添加到每个项目。

关于iis-7 - 通过 MSBuild 在 Web 部署期间设置 ACL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12908683/

相关文章:

msbuild - 如何通过 msbuild/msdeploy 部署 .net core rc2 项目?

c# - 64 位 IIS7 不会运行 32 位 dll,即使启用了 32 位

sql-server - 网站从 IIS6 迁移到 IIS7 后经典 asp 数据库连接出错

asp.net - 如何在 IIS 中启用字节范围的 http 请求

asp.net-mvc - httpErrors errorMode = "Detailed"仅适用于特定错误代码

delphi - 为什么通过 MSBuild 编译比通过 IDE 编译花费的时间长得多?

msbuild - 在CruiseControl.NET中使用MSTest

msbuild - 如何将转换应用于 SSDT 发布配置文件

deployment - 如何执行自动化部署 - 使用 Pull 模型

TFS 2012 Team Build 和 Web 应用程序部署 - ERROR_USER_NOT_ADMIN