daviddelombaerde Ответов: 2

Получить доступ к сети


Привет,

Что я пытаюсь сделать:
Я вошел в систему как обычный пользователь, без прав администратора.

У меня есть учетная запись администратора, которую я могу использовать для доступа к другим ноутбукам в сети.
Я вручную захожу в проводник, заполняю \ \ PCID\C$\Path, получаю диалоговое окно windows-security, где windows запрашивает сетевую аутентификацию и где я заполняю свои учетные данные администратора.

Я пытаюсь создать приложение wpf на c#, где я хочу что-то автоматизировать.
У меня есть listview со всеми пользователями в нашем отделе, и я хочу иметь возможность выбрать некоторых пользователей и получить доступ к пути на их ноутбуке.

try
{
foreach (INFR_Gebruiker user in ListUsers_LV.SelectedItems)
{
string pcId = user.PcId;
ProcessStartInfo psi = new ProcessStartInfo("explorer", $@"\\{pcId}\c$\programdat\Autodesk");
Process.Start(psi);
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
}


Но в тот момент, когда приложение пытается получить доступ к сетевой аутентификации, появляется всплывающее окно.

Есть ли способ избежать этого?

Что я уже пробовал:

То, что я пытался сделать, это:
1. прикрепите Манифест к приложению, чтобы оно всегда запрашивало admin cred для запуска:
<pre><?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="IsUserAdmin" type="win32"/>
  <description>POA_CADControlCenter</description>
  <!-- Identify the application security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel

          level="requireAdministrator"

          uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>


2. Я пытался реализовать класса windowsidentity.Метод Олицетворения:

Я использовал этот пример и просто добавил process. start () После успешного олицетворения:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;


public class ImpersonationDemo
{
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    // Test harness.
    // If you incorporate this code into a DLL, be sure to demand FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main(string[] args)
    {
        SafeTokenHandle safeTokenHandle;
        try
        {
            string userName, domainName;
            // Get the user token for the specified user, domain, and password using the
            // unmanaged LogonUser method.
            // The local machine name can be used for the domain name to impersonate a user on this machine.
            Console.Write("Enter the name of the domain on which to log on: ");
            domainName = Console.ReadLine();

            Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
            userName = Console.ReadLine();

            Console.Write("Enter the password for {0}: ", userName);

            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);

            Console.WriteLine("LogonUser called.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            using (safeTokenHandle)
            {
                Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);

                // Check the identity.
                Console.WriteLine("Before impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
                // Use the token handle returned by LogonUser.
                using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
                {

                    // Check the identity.
                    Console.WriteLine("After impersonation: "
                        + WindowsIdentity.GetCurrent().Name);
                }
                // Releasing the context object stops the impersonation
                // Check the identity.
                Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }

    }
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private SafeTokenHandle()
        : base(true)
    {
    }

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr handle);

    protected override bool ReleaseHandle()
    {
        return CloseHandle(handle);
    }
}

Richard Deeming

Вы пробовали установить Domain, UserName и Password свойства на ProcessStartInfo?

2 Ответов

Рейтинг:
18

Jochen Arndt

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

Если вы можете выполнять необходимые задачи, используя сетевое подключение к общим ресурсам вместо запуска проводника, вы можете создать его.

Одним из вариантов является использование Класс NetworkCredential (System.Net)[^]. Видеть Доступ к удаленной папке[^] для примера.

Существует также статья здесь на CP с использованием NetApi32: Подключение к UNC-пути с учетными данными[^].

Еще больше можно найти, поискав в интернете что-то вроде "C# credentials network share".


Рейтинг:
1

daviddelombaerde

Я использовал этот пример: Подключение к UNC-пути с учетными данными[^].

Мне не нужен был список всех подпапок в пути UNC, но мне нужно было открыть это место в проводнике. Поэтому я приспособил это к:

public void Explorer_Click(object sender, RoutedEventArgs e)
       {

           System.Windows.Forms.Application.DoEvents();

           try
           {
               foreach (INFR_Gebruiker user in ListUsers_LV.SelectedItems)
               {
                   string pcId = user.PcId;
                   string path = $@"\\{pcId}\c$";
                   var uri = new System.Uri($@"\\{pcId}\c$");

                   using (UNCAccessWithCredentials unc =
                                           new UNCAccessWithCredentials())
                   {
                       if (unc.NetUseWithCredentials(path,
                                              "username","domain","password"))
                       Process.Start("explorer", uri.AbsoluteUri);
                   }
               }
           }
           catch (Exception ex) { MessageBox.Show(ex.Message); }
       }