на моем веб-сайте (написано в 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: Следующие шаги, которые я предпринял, включают это:
- Создание пула приложений, в котором идентификация установлена для пользователя (который является членом группы администраторов).
- Установить услугу «вход в систему» для того же пользователя.
- После повторного запуска веб-приложения оно все еще не работает ..
Однако Если я добавлю учетную запись Администратора в качестве учетных данных в коде, она будет работать .. (Даже если я не использовал Администратора в Пуле приложений и в службе ...)
Другими словами, я могу получить то, что хочу, с учетной записью администратора, но не с учетной записью, которую я создал сам и у которой есть права администратора. Я все еще хочу, чтобы эта работа работала с пользователем, которого я сделал сам, поскольку считаю, что не совсем безопасно размещать ваши учетные данные администратора.
На sidenote, на сервере, на котором я работаю, есть учетная запись, которая имеет права администратора, но не является учетной записью администратора.
РЕДАКТИРОВАТЬ 3: Это становится странным. Кажется, я сейчас работаю, НО:
- без метода олицетворения (это не сработало).
- Я просто сделал то, что сказал Роб. У меня есть собственный пул приложений с пользователем, которого я определил. Служба Windows также указала этого пользователя. (Пользователь получил право на вход в систему как сервис)
- С этим, похоже, работает.
- Но если отладка через мой сайт, я все равно получаю отказано в доступе. Но если я просто захожу на мой сайт через браузер и его ip, я могу запустить службу.
Подводя итог:
- Метод подражания не работает.
- Просто использование пула приложений, созданного самим пользователем, с правильным пользователем работает, если в службе также указан пользователь. Но он не работает в режиме отладки (все равно Acces Denied там).
Этот пост становится большим, и мне интересно, действительно ли кто-нибудь еще его читает ... Но, может быть, кто-то еще может дать мне какие-нибудь подробности? Я боюсь, что это снова не удастся где-то в будущем ..
Любой комментарий будет оценен!
Floris