以编程方式修改 ACL 以授予应用程序池对应用程序 (IIS) 的所有权限

Programmatically modify ACL to give application pool all permissions to application (IIS)

我有一个使用Microsoft.Web.Administration命名空间中的服务器管理器对象创建应用程序和应用程序池的进程,先创建应用程序池,然后再创建应用程序,将新创建的应用程序池分配给应用程序,代码如下。

protected TResult UseServerManagerWrapper<TResult>(Func<ServerManager, TResult> func)
    {
        using (var serverManager = new ServerManager())
        {
            return func(serverManager);
        }
    }

应用创建功能

public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
    {
        UseServerManagerWrapper(serverManager =>
            {
                var site = serverManager.Sites[siteName];

                var newApplication =
                    site.Applications.Add(
                        GetApplicationPath(parentApplicationName, organisationName, applicationName),
                        this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName));

                newApplication.ApplicationPoolName = applicationPoolName;
                serverManager.CommitChanges();
                return true;
            });
    }

和应用程序池创建。

public Boolean CreateApplicationPool(String applicationPoolName)
    {
        return UseServerManagerWrapper(serverManager =>
            {
                var appPool = serverManager.ApplicationPools.Add(applicationPoolName);

                appPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
                appPool.ManagedRuntimeVersion = "";
                serverManager.CommitChanges();
                return true;
            });
    }

一切正常,唯一的问题是我必须进入应用程序文件夹并手动为应用程序池分配权限。

我在 ServerManager 文档中看不到任何可以帮助我的东西,我也想不出使用 Directory.SetAccessControl 方法来授予应用程序池权限的方法。有没有办法在代码中做到这一点?

如果我使用了错误的术语或其他任何内容,我深表歉意,我是一般出版业的新手。如果您需要更多信息,请告诉我。

好的,经过大量搜索和反复试验后,我找到了解决方案,它与 ServerManager 对象无关。首先要让它在 ASP.NET Core 2.1 (1.x/2.x) 中工作,我需要 System.IO.FileSystem.AccessControl Nuget 和下面的命名空间。

using System.Security.AccessControl;
using System.Security.Principal;

这些提供了修改文件和文件夹的ACL的能力,然后CreateApplication函数就变成了下面的。

public void CreateApplication(String siteName, String parentApplicationName, String organisationName, String applicationName, String applicationPoolName)
    {
        UseServerManagerWrapper(serverManager =>
            {
                var site = serverManager.Sites[siteName];
                var generatedPath = this.GetGeneratedApplicationPhysicalPath(siteName, parentApplicationName, organisationName, applicationName);
                var newApplication =
                    site.Applications.Add(
                        GetApplicationPath(parentApplicationName, organisationName, applicationName),
                        generatedPath);

                newApplication.ApplicationPoolName = applicationPoolName;

                var dInfo = new DirectoryInfo(generatedPath);
                var acl = dInfo.GetAccessControl();
                var acct = new NTAccount($"IIS APPPOOL\{applicationPoolName}");
                acl.AddAccessRule(new FileSystemAccessRule(acct, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
                dInfo.SetAccessControl(acl);

                serverManager.CommitChanges();
                return true;
            });
    }

"newApplication.ApplicationPoolName = applicationPoolName" 和 "serverManager.CommitChanges()" 之间的代码从新生成的目录获取 ACL,从而能够修改它并使用新的 FileSystemAccessRule 重新分配。