Запуск службы в ASP.NET/C# с ​​необходимыми разрешениями - PullRequest
0 голосов
/ 20 мая 2011

на моем веб-сайте (написано в 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 на компьютере» с дополнительным сообщением: «Доступ запрещен».

Я знаю, что это проблема с разрешениями, но как мне дать себе соответствующие разрешения? Не приходите с ответом, где я должен написать: потому что я пробовал, и это не сработало. Также я думаю, что это не самый лучший способ настроить это для всего сайта, когда мне просто нужно это для этих нескольких строк кода.

РЕДАКТИРОВАТЬ: Я добавил это в свой код, и он все еще не работает, я получаю такое же исключение в том же месте. Теперь это выглядит так:

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
        }
    }
}

У меня есть класс Impersonate, который выглядит так:

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. Создание пула приложений, в котором идентификация установлена ​​для пользователя (который является членом группы администраторов).
  2. Установить услугу «вход в систему» ​​для того же пользователя.
  3. После повторного запуска веб-приложения оно все еще не работает ..

Однако Если я добавлю учетную запись Администратора в качестве учетных данных в коде, она будет работать .. (Даже если я не использовал Администратора в Пуле приложений и в службе ...)

Другими словами, я могу получить то, что хочу, с учетной записью администратора, но не с учетной записью, которую я создал сам и у которой есть права администратора. Я все еще хочу, чтобы эта работа работала с пользователем, которого я сделал сам, поскольку считаю, что не совсем безопасно размещать ваши учетные данные администратора.

На sidenote, на сервере, на котором я работаю, есть учетная запись, которая имеет права администратора, но не является учетной записью администратора.

РЕДАКТИРОВАТЬ 3: Это становится странным. Кажется, я сейчас работаю, НО: - без метода олицетворения (это не сработало). - Я просто сделал то, что сказал Роб. У меня есть собственный пул приложений с пользователем, которого я определил. Служба Windows также указала этого пользователя. (Пользователь получил право на вход в систему как сервис) - С этим, похоже, работает. - Но если отладка через мой сайт, я все равно получаю отказано в доступе. Но если я просто захожу на мой сайт через браузер и его ip, я могу запустить службу.

Подводя итог: - Метод подражания не работает. - Просто использование пула приложений, созданного самим пользователем, с правильным пользователем работает, если в службе также указан пользователь. Но он не работает в режиме отладки (все равно Acces Denied там).

Этот пост становится большим, и мне интересно, действительно ли кто-нибудь еще его читает ... Но, может быть, кто-то еще может дать мне какие-нибудь подробности? Я боюсь, что это снова не удастся где-то в будущем ..

Любой комментарий будет оценен! Floris

1 Ответ

2 голосов
/ 20 мая 2011

Вы должны убедиться, что ваш веб-сайт работает под пользователем, который имеет достаточно прав для запуска службы.Также убедитесь, что анонимная проверка подлинности отключена в IIS. Хорошим способом может быть создание пользователя, обладающего правами на запуск службы в сети сервера, а затем создание пула приложений, который запускается под этим пользователем. Затем необходимо использовать веб-сайт.этот пул приложений.При таком подходе весь веб-сайт будет работать под пользователем, которого вы только что создали.Если вы хотите быть более детализированным, вы все равно можете создать пользователя, у которого есть права на запуск службы, но вместо того, чтобы использовать его для пула приложений, вы можете сделать только страницу, которая должна запустить службу, под этим пользователем, используя олицетворение.Вы можете использовать функцию импорсации только для этого метода!

для получения более подробной информации смотрите ссылки ниже:

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

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

...