C # - Как аутентифицироваться на сервере динамически - PullRequest
0 голосов
/ 08 ноября 2018

Мне нужно проверить, работает ли служба «Совет» на указанном сервере. Я сделал метод, который делает именно это:

public static bool CheckServicesFromServer(string pServicos)
        {
        ServiceController service = new ServiceController();
        List<string> Servicos = pServicos.Split(',').Select(p => p.Trim()).ToList();

        if (Config.BaseLogin == BasesSistema.QualityLogin)
            service.MachineName = "quality";
        if (Config.BaseLogin == BasesSistema.TS02Login)
            service.MachineName = "ts02";
        if (Config.BaseLogin == BasesSistema.TS03Login)
            service.MachineName = "ts03";
        if (Config.BaseLogin == BasesSistema.LocalHost)
            service.MachineName = Environment.MachineName;

        try
        {
            foreach (var item in Servicos)
            {
                service.ServiceName = item;

                if ((service.Status.Equals(ServiceControllerStatus.Stopped)) || (service.Status.Equals(ServiceControllerStatus.StopPending)))
                {
                    File.AppendAllText(StatusLog.StatusLocation, "O servico " + service.ServiceName + " está parado. a Regra não será gerada.");
                    throw new Exception();
                }

                if (service.Status.Equals(ServiceControllerStatus.Running))
                {
                    File.AppendAllText(StatusLog.StatusLocation, "O serviço " + service.ServiceName + "está rodando perfeitamente.");
                }
            }
        }

        catch (Exception e)
        {
            Log.WriteErrorLog(e.Message);
            throw new Exception(e.Message);
        }

        return true;
    }

Дело в том, что когда я запускаю тест, он говорит "Доступ запрещен" и выдает исключение. Когда я добавляю своего пользователя (пользователя с компьютера, на котором выполняется приложение) в качестве Adm на сервере, он работает нормально.

Есть ли способ аутентификации моего компьютера, чтобы у него было разрешение на доступ к серверу и проверку статуса его обслуживания?

1 Ответ

0 голосов
/ 09 ноября 2018

Благодаря Крику я нашел решение. Это так же просто, как добавить этот класс:

using System;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Security.Permissions;

public class ImpersonateUser
{
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(
    String lpszUsername,
    String lpszDomain,
    String lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);
    private static IntPtr tokenHandle = new IntPtr(0);
    private static WindowsImpersonationContext impersonatedUser;
    // If you incorporate this code into a DLL, be sure to demand that it
    // runs with FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public void Impersonate(string domainName, string userName, string password)
    {
        //try
        {
            // Use the unmanaged LogonUser function to get the user token for
            // the specified user, domain, and password.
            const int LOGON32_PROVIDER_DEFAULT = 0;
            // Passing this parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;
            tokenHandle = IntPtr.Zero;
            // ---- Step - 1
            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(
            userName,
            domainName,
            password,
            LOGON32_LOGON_INTERACTIVE,
            LOGON32_PROVIDER_DEFAULT,
            ref tokenHandle); // tokenHandle - new security token
            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                throw new System.ComponentModel.Win32Exception(ret);
            }
            // ---- Step - 2
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            // ---- Step - 3
            {
                impersonatedUser = newId.Impersonate();
            }
        }
    }
    // Stops impersonation
    public void Undo()
    {
        impersonatedUser.Undo();
        // Free the tokens.
        if (tokenHandle != IntPtr.Zero)
        {
            CloseHandle(tokenHandle);
        }
    }

    internal void Impersonate()
    {
        throw new NotImplementedException();
    }
}

И я просто должен был назвать это так:

public static bool CheckServicesFromServer(string pServicos)
        {
            ImpersonateUser Iu = new ImpersonateUser();
            ServiceController service = new ServiceController();
            List<string> Servicos = pServicos.Split(',').Select(p => p.Trim()).ToList();

            if (Config.BaseLogin == BasesSistema.QualityLogin)
                service.MachineName = "quality";
            if (Config.BaseLogin == BasesSistema.TS02Login)
                service.MachineName = "ts02";
            if (Config.BaseLogin == BasesSistema.TS03Login)
                service.MachineName = "ts03";
            if (Config.BaseLogin == BasesSistema.LocalHost)
                service.MachineName = Environment.MachineName;

            Iu.Impersonate(Config.Dominio, Config.LoginMaster, Config.SenhaMaster);

            try
            {
                foreach (var item in Servicos)
                {
                    service.ServiceName = item;

                    if ((service.Status.Equals(ServiceControllerStatus.Stopped)) || (service.Status.Equals(ServiceControllerStatus.StopPending)))
                    {
                        Flag = true;
                        File.AppendAllText(StatusLog.StatusLocation, "O servico " + service.ServiceName + " está parado. a Regra não será gerada. <br />");
                        throw new Exception();
                    }

                    if (service.Status.Equals(ServiceControllerStatus.Running))
                    {
                        File.AppendAllText(StatusLog.StatusLocation, "O serviço " + service.ServiceName + " está rodando perfeitamente. <br />");
                    }
                }
                Iu.Undo();
            }

            catch
            {
                Iu.Undo();
                Log.WriteErrorLog("Não é possível abrir o Gerenciador de Controle de Serviços no Computador '" + service.MachineName + "'. <br />");
                return false;
            }
            return true;
        }

Мой Config Класс содержит информацию о Домене, Пользователе и PassWord, и он работал отлично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...