6

問題:新しい IIS アプリケーション プールが作成され、アクセス許可にアプリケーション プール ID を使用するように設定されている場合、これらの ID を管理者やパフォーマンス カウンター ユーザーなどのユーザー グループに追加する方法がわかりません。

背景:現在、次のことを行うために Microsoft.Web.Administration を使用する C#.NET ライブラリを作成しています。

  • IIS 7.x がインストールされているかどうかを検出し、インストールされている場合はどのコンポーネントかを検出します。
  • IIS 7.x を必要なコンポーネントの提供されたリストにインストールまたはアップグレードします。
  • IIS を介して 1 つまたは複数の Web サイトを作成/管理します。
  • Web サイトごとに 1 つのアプリケーション プールを自動的に作成/管理

このライブラリは、大規模なソフトウェア展開の一部として、Windows Server OS 上で Web サーバーおよび Web サイト/サービスの自動展開を提供するために、実行可能インストーラーによって使用されるということです。これまでのところ、アプリケーション プール/Web サイトの作成で実行する必要があるいくつかのアクセス許可の自動化を除いて、上記のすべてが実装、テストされ、(ほとんど) 機能しています。

新しい Web サイトをインストールするための私の方法では、新しいアプリケーション プールを作成し、アプリケーション プール ID を使用するように強制します。

static public void InstallSite(string name, string path, int port)
{
    Site site;
    var appPoolName = ApplicationPoolBaseName + name;

    using (var iisManager = new ServerManager())
    {
        // Set up a custom application pool for any site we run.
        if (!iisManager.ApplicationPools.Any(pool => pool.Name.Equals(appPoolName)))
        {
            iisManager.ApplicationPools.Add(appPoolName);
            iisManager.ApplicationPools[appPoolName].ManagedRuntimeVersion = "v4.0";
        }
        iisManager.CommitChanges();
    }

    // ... other code here ('site' gets initialized) ...

    using (var iisManager = new ServerManager())
    {
        // Set anonymous auth appropriately
        var config = iisManager.GetWebConfiguration(site.Name);
        var auth = config.GetSection("system.web/authentication");
        auth.SetMetadata("mode", "Windows");
        var authSection = config.GetSection("system.webServer/security/authentication/anonymousAuthentication");
        authSection.SetAttributeValue("enabled", true);
        authSection.SetAttributeValue("userName", string.Empty); // Forces the use of the Pool's Identity.
        authSection = config.GetSection("system.webServer/security/authentication/basicAuthentication");
        authSection.SetAttributeValue("enabled", false);
        authSection = config.GetSection("system.webServer/security/authentication/digestAuthentication");
        authSection.SetAttributeValue("enabled", false);
        authSection = config.GetSection("system.webServer/security/authentication/windowsAuthentication");
        authSection.SetAttributeValue("enabled", false);

        iisManager.CommitChanges();
    }

    // ... other code here ...
}

私が理解しているように、これが最善のセキュリティ プラクティスであり、特定の Web サイトに最小限のシステム アクセス以上のアクセス許可を追加します。このプロセスの一部として、これらのアプリケーション プール ID を管理者やパフォーマンス モニター ユーザーなどのユーザー グループに追加します。ここで合併症が発生します。

現在、他の場所で文書化されているように、各アプリケーション プール ID は の形式で存在しますがIIS AppPool\\<pool_name>、この偽のユーザーは、通常の GUI ユーザー管理コントロールを介してリストされておらず、 SO でこの例System.DirectoryServices.AccountManagementに従う場合など、ライブラリを介してアクセスできないようです。また、アプリケーション プール ID に関する他の質問は、インストール コンテキスト内からではなく、子 Web サイト内からの参照に関連しているようです。

それで、誰かが適切な方法が何であるかを知っていますか

  • a) プログラムによるアプリケーション プール ID の参照とアクセス。
  • b) ユーザー グループを追加して、アプリケーション プール ID のアクセス許可を付与します。
4

2 に答える 2

1

解決策は私が好んだものではありませんが、私が予想したよりも早く現れました。興味のある方は、このpinvokeページにいくつかの追加オプションがあります。マネージドソリューションは機能しませんでしたが、DllImportを使用したサンプルは機能しました。列挙型をSID文字列にマッピングし、次の別のDllImportを含めることに基づいて、任意のグループを処理するようにサンプルを調整することになりました。

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool ConvertStringSidToSid(
    string StringSid,
    out IntPtr ptrSid);

変更された(動作中の)関数は次のようになります。

static public bool AddUserToGroup(string user, UserGroup group)
{
    var name = new StringBuilder(512);
    var nameSize = (uint)name.Capacity;
    var refDomainName = new StringBuilder(512);
    var refDomainNameSize = (uint)refDomainName.Capacity;
    var sid = new IntPtr();
    switch (group)
    {
        case UserGroup.PerformanceMonitorUsers:
            ConvertStringSidToSid("S-1-5-32-558", out sid);
            break;
        case UserGroup.Administrators:
            ConvertStringSidToSid("S-1-5-32-544", out sid);
            break;
        // Add additional Group/cases here.
    }

    // Find the user and populate our local variables.
    SID_NAME_USE sidType;
    if (!LookupAccountSid(null, sid, name, ref nameSize,
        refDomainName, ref refDomainNameSize, out sidType))
        return false;

    LOCALGROUP_MEMBERS_INFO_3 info;
    info.Domain = user;

    // Add the user to the group.
    var val = NetLocalGroupAddMembers(null, name.ToString(), 3, ref info, 1);

    // If the user is in the group, success!
    return val.Equals(SUCCESS) || val.Equals(ERROR_MEMBER_IN_ALIAS);
}

うまくいけば、これは他の誰かの興味を引くでしょう、そして私はまだ誰かが機能している、完全に管理された解決策に出くわしたかどうか知りたいです。

于 2013-02-06T14:27:57.053 に答える