C# 使用用户名和密码启动进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17908993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Starting a process with a user name and password
提问by Yonatan Nir
I know that you can run a process with a given username/password in the following way:
我知道您可以通过以下方式使用给定的用户名/密码运行进程:
var processInfo = new ProcessStartInfo
{
WorkingDirectory = workingDirectory,
FileName = "a name",
UserName = loggedUserName,
Password = "password",
Domain = userNameDomain,
UseShellExecute = false,
};
Process.Start(processInfo);
The problem I'm facing is that I don't want to write the actual password as a part of the code and the process won't start if I leave the Password attribute empty... How can I safely start the process without exposing the password as a hard coded string in the code?
我面临的问题是,我不想将实际密码写为代码的一部分,如果我将 Password 属性留空,则该过程将无法启动......如何在不暴露的情况下安全地启动该过程密码作为代码中的硬编码字符串?
采纳答案by Steve
The ProcessStartInfo.Passwordis not a simple string that you can write down and assign to the property. What you need is a SecureStringinstance and a SecureString cannot be created passing a simple string to its constructor. Obviously the OS has no API or method that allows a non trusted program to retrieve the password of the current user (it would be the biggest security bug ever heard of).
该ProcessStartInfo.Password不是一个简单的字符串,你可以写下来,并分配给属性。您需要的是一个SecureString实例,并且不能通过将简单字符串传递给其构造函数来创建 SecureString。显然,操作系统没有允许不受信任的程序检索当前用户密码的 API 或方法(这将是有史以来最大的安全漏洞)。
So, in my thinking, you are left with only one option. Ask your user to type again the password and the resulting input should be transformed into a SecureString
所以,在我看来,你只有一种选择。要求您的用户再次输入密码,结果输入应转换为 SecureString
This example is an extension method for the string class that 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;
}
}
}
you could use it to transform the password typed by your user and start the process
您可以使用它来转换用户输入的密码并启动该过程
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);
}
}
回答by uTILLIty
I use the windows Password store to manage such passwords. Check out the http://credentialmanagement.codeplex.com/library which wraps around the windows API. Either your Setup-Routine or Admin can add the password to the store, which can then be retrieved at runtime from the application. Only drawback is that the store is user-specific. You can't create a password which can be used across multiple users.
我使用 Windows 密码存储来管理此类密码。查看包含 Windows API的http://credentialmanagement.codeplex.com/库。您的 Setup-Routine 或 Admin 可以将密码添加到商店,然后可以在运行时从应用程序中检索密码。唯一的缺点是商店是特定于用户的。您无法创建可跨多个用户使用的密码。
It's as simple as that:
就这么简单:
_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);
}