使用用户名和密码启动进程

时间:2013-07-28 14:02:30

标签: c# username process.start processstartinfo

我知道您可以通过以下方式运行具有给定用户名/密码的进程:

var processInfo = new ProcessStartInfo
  {
      WorkingDirectory = workingDirectory,
      FileName = "a name",
      UserName = loggedUserName, 
      Password = "password",
      Domain = userNameDomain,
      UseShellExecute = false,
  };
  Process.Start(processInfo);

我面临的问题是我不想将实际密码写为代码的一部分,如果我将密码属性留空,则进程将无法启动...如何安全地启动进程没有将密码作为代码中的硬编码字符串公开?

2 个答案:

答案 0 :(得分:7)

ProcessStartInfo.Password不是一个简单的字符串,您可以记下并分配给该属性。您需要的是SecureString实例,并且无法创建SecureString,将简单字符串传递给其构造函数。显然,操作系统没有API或方法允许不受信任的程序检索当前用户的密码(这将是有史以来最大的安全漏洞)。

所以,在我的想法中,你只剩下一个选择。让您的用户再次输入密码,结果输入应转换为SecureString

此示例是I have seen here

的字符串类的扩展方法
using System.Security;

// ...

public static SecureString ConvertToSecureString(this string password)
{
    if (password == null)
        throw new ArgumentNullException("password");

    unsafe
    {
        fixed (char* passwordChars = password)
        {
            var securePassword = new SecureString(passwordChars, password.Length);
            securePassword.MakeReadOnly();
            return securePassword;
        }
    }
}

您可以使用它来转换用户输入的密码并启动流程

using(frmGetPassword fgp = new frmGetPassword())
{
     if(DialogResult.OK == fgp.ShowDialog())
     {
         SecureString ss = fgp.Password.ConvertToSecureString();
         var processInfo = new ProcessStartInfo
         {
             WorkingDirectory = workingDirectory,
             FileName = "a name",
             UserName = loggedUserName, 
             Password = ss,
             Domain = userNameDomain,
             UseShellExecute = false,
         };
         Process.Start(processInfo);
     }
}

答案 1 :(得分:1)

我使用Windows密码存储来管理此类密码。查看包含Windows API的http://credentialmanagement.codeplex.com/库。您的Setup-Routine或Admin可以将密码添加到商店,然后可以在运行时从应用程序中检索该密码。唯一的缺点是商店是用户特定的。您无法创建可在多个用户中使用的密码。

就这么简单:

        _credentials = new CredentialSet("myApp:*");
        if (_credentials.Count == 0)
        {
            //TODO: ask user for password, supply it here, or use windows UI to set password (rundll32.exe keymgr.dll, KRShowKeyMgr)
            var c = new Credential()
            {
                Target = "myApp:Production",
                Username = "SomeUser",
                Description = "Credentials for doing something...",
                PersistanceType = PersistanceType.LocalComputer,
                Type = CredentialType.DomainPassword
            };
            c.Save();
            _credentials.Add(c);
        }