0

私のWebサイト(ASP.NET/C#で記述)で、モデレーターが特定のサービスを開始できるようにしたい。私がこれのために持っているコードは次のとおりです:

    ServiceController svcController = new ServiceController("InvidualFileConversion");

    if (svcController != null)
    {
        try
        {
            svcController.Stop();
            svcController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
            svcController.Start();
        }
        catch (Exception ex)
        {
            // error
        }
    }

これを実行すると、「コンピューターでInvidualFileConversionサービスを開くことができません」というエラーが表示され、「アクセスが拒否されました」という追加のメッセージが表示されます。

これが権限の問題であることは知っていますが、適切な権限を自分に与えるにはどうすればよいですか? 私が書くべき答えを持って来ないでください:、私がそれを試したのにそれがうまくいかなかったからです。また、これらの数行のコードで必要な場合は、これをWebサイト全体に設定するのに最適な方法ではないと思います。

編集:これをコードに追加しましたが、それでも機能しません。同じ場所で同じ例外が発生します。これで、次のようになります。

protected void ConvertLink_OnClick(object sender, EventArgs e)
{
    //convert();
    try
    {
        //--need to impersonate with the user having appropriate rights to start the service
        Impersonate objImpersonate = new Impersonate(domainName, userName, userPassword);
        if (objImpersonate.impersonateValidUser())
        {
            //--write code to start/stop the window service
            startWindowsService();
            objImpersonate.undoImpersonation();
        }
    }
    catch (Exception Ex)
    { Response.Write(Ex.Message + Ex.InnerException.Message); }
}

private void startWindowsService()
{
    ServiceController svcController = new ServiceController("InvidualFileConversion");

    if (svcController != null)
    {
        try
        {
            svcController.Stop();
            svcController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10));
            svcController.Start();
        }
        catch (Exception ex)
        {
            // error
        }
    }
}

私は次のような偽装クラスを持っています:

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Security.Principal;
using System.Runtime.InteropServices;

/// <summary>
/// Summary description for Impersonate
/// </summary>
public class Impersonate
{

#region "Class Members"
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
#endregion

#region "Class Properties"
public string domainName { get; set; }
public string userName { get; set; }
public string userPassword { get; set; }
#endregion

public Impersonate()
{
    //
    // TODO: Add constructor logic here
    //
}
public Impersonate(string domainName, string userName, string userPassword)
{
    this.domainName = domainName;
    this.userName = userName;
    this.userPassword = userPassword;
}

#region "Impersonation Code"
[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
    String lpszDomain,
    String lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken,
    int impersonationLevel,
    ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
public bool impersonateValidUser()
{
    WindowsIdentity tempWindowsIdentity;
    IntPtr token = IntPtr.Zero;
    IntPtr tokenDuplicate = IntPtr.Zero;

    if (RevertToSelf())
    {
        if (LogonUserA(this.userName, this.domainName, this.userPassword, LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT, ref token) != 0)
        {
            if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
            {
                tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                impersonationContext = tempWindowsIdentity.Impersonate();
                if (impersonationContext != null)
                {
                    CloseHandle(token);
                    CloseHandle(tokenDuplicate);
                    return true;
                }
            }
        }
    }
    if (token != IntPtr.Zero)
        CloseHandle(token);
    if (tokenDuplicate != IntPtr.Zero)
        CloseHandle(tokenDuplicate);
    return false;
}

public void undoImpersonation()
{
    impersonationContext.Undo();
}
#endregion
}

したがって、検証は機能しますが、問題は解決しません。権限にまだ問題があると思います。これを変更するにはどうすればよいですか。

編集2:私が取った次のステップはこれを含みます:

  1. IDがユーザー(管理者グループのメンバー)に設定されるアプリプールを作成します。
  2. サービスの「ログオン」を同じユーザーに設定します。
  3. Webアプリを再度実行した後も、失敗します。

ただし、コードにクレデンシャルとして管理者アカウントを入力すると、機能します。(アプリプールとサービスで管理者を使用しなかった場合でも...)

つまり、Administratorアカウントでは必要なものを取得できますが、自分で作成して管理者権限を持つアカウントでは取得できません。管理者の資格情報を利用できるようにするのはそれほど安全ではないと思うので、自分で作成したユーザーでこれを機能させたいと思っています。

ちなみに、私が作業しているサーバーには、管理者権限はあるが「管理者」アカウントではないアカウントがあります。

編集3:これは奇妙になっています。私は今は機能しているようですが:-偽装方法なしで(機能しませんでした)。-ロブが言ったことをやっただけです。定義したユーザーを持つ独自のアプリケーションプールがあります。Windowsサービスには、そのユーザーも指定されています。(ユーザーはサービスとしてログオンする権利を受け取りました)-これで、動作しているようです。-しかし、私のWebサイトでデバッグすると、アクセスが拒否されます。しかし、ブラウザとそのIPを介して自分のWebサイトにアクセスするだけで、サービスを開始できます。

要約すると:-なりすまし方法は機能しません。-サービスにユーザーも指定されている場合は、currectユーザーで自分で作成したアプリプールを使用するだけで機能します。ただし、デバッグモードでは機能しません(まだアクセスが拒否されています)。

この投稿は大きくなりつつあり、まだ実際に読んでいる人はいないかと思います。しかし、それでも誰かが私に詳細を教えてくれるでしょうか。将来どこかでまた失敗するのではないかと思います。

コメントをいただければ幸いです。フローリス

4

1 に答える 1

2

サービスを開始するのに十分な権限を持つユーザーの下で Web サイトが実行されていることを確認する必要があります。IIS で匿名認証が無効になっていることも確認してください。良い方法は、サーバー Web でサービスを開始する権限を持つユーザーを作成し、そのユーザーの下で実行されるアプリケーション プールを作成することです。次に、Web サイトで使用する必要があります。そのアプリケーション プール。このアプローチを使用すると、作成したばかりのユーザーの下ですべての Web サイトが実行されます。より細かくしたい場合は、サービスを開始する権限を持つユーザーを作成することもできますが、それをアプリケーション プールに使用する代わりに、偽装を使用してサービスを開始する必要があるページのみをそのユーザーの下で実行することができます。なりすまし機能が使えるのはこの方法だけ!

詳細については、以下のリンクをご覧ください。

http://forums.asp.net/t/1137962.aspx/1

http://support.microsoft.com/kb/306158

于 2011-05-20T10:35:13.723 に答える