可重复使用的“保存凭证” .NET 或 Win32 中的对话框(如 IE 或 Vista)
最近,我在一个拥有无线网络的办公室工作,该网络使用令人讨厌的身份验证方案:每隔几个小时,您需要打开浏览器并在身份验证网页中输入用户名/密码,否则您将失去网络访问权限。 (当时间到期时,您的下一个浏览器请求将重定向到身份验证页面,如果您的信用通过了审核,那么您将被重定向回您最初尝试访问的页面)。
对于机场或咖啡厅的无线网络来说,这种烦恼可能还好,但在办公室中,这就令人恼火了——尤其是当您使用网络服务(例如 SVN、电子邮件)时,这些服务每隔几个小时就会突然停止工作,除非您提出浏览器。
因此,我编写了一个小型 C# 控制台应用程序,它将通过使用我的凭据向登录表单发送 HTTP 请求来为我登录。
这显然是不安全的——我的密码位于我的源代码中,所有人都可以看到。我希望能够使用 IE 用来保存和重新填写 Web 表单中的密码的相同机制来保存我的凭据。
理想情况下,我想要一个可重复使用的组件,用于输入、保存和检索凭据(包括带有可选“保存凭据”复选框的 UI),以便我的应用程序可以简单地执行类似这样的操作(以伪代码形式):
// retrieve any saved credentials from some secure place
Credentials creds = GetCreds(some parameters go here);
// if none stored, then show the user an "enter and optionally save credentials" dialog
if (creds == null)
creds = GetCredsDialog(some parameters go here);
// POST to the authentication page
if (creds != null)
{
string authUrl = "https://somehost/login/";
string postDataPattern = "post data pattern here";
// use SecureString here instead?
string postData = string.Format (postDataPattern, HttpUtility.HtmlEncode(creds.Username), HttpUtility.HtmlEncode(creds.Password));
WebClient wc = new WebClient();
string html = wc.UploadString (authUrl, "POST", postData);
// TODO: if html indicates login failure, clear stored credentials
// and ask for new creds. then retry.
}
本质上我想要将安全存储信用的负担从我的应用程序转移到 Windows,假设 Windows 人员在这方面比我做得更好。 :-)
我在这里并不是在寻找铁定的安全性,只是寻找与 IE 用来保护我在其他网站上存储的其他密码类似的东西。我只是不想在我的代码中保留纯文本密码!
当然,正确的解决方案是与 IT 部门合作,让他们获得真正的无线身份验证方案,但与此同时,我只能靠自己了。
.NET 解决方案会更好,但 Win32 解决方案也可以——我可以简单地将应用程序移植到 C++,而不会有太多麻烦。
Lately I've been working in an office with a wireless network which uses an annoying authentication scheme: every few hours, you need to open up a browser and type a username/password into an authentication web page, or you lose network access. (When the time expires, your next browser request will redirect to the auth page, and if your creds pass muster, then you'll be redirected back to the page you were trying to get to originally).
This kind of annoyance may be OK for an airport or coffee shop wireless, but in an office it's infuriating-- especially if you're working with network services (e.g. SVN, email) which suddenly stop working every few hours unless you bring up a browser.
So I have written a tiny C# console app which will log in for me by sending an HTTP request to the login form with my credentials.
This is obviously insecure-- my password is sitting inside my source code for all to see. I'd prefer to be able to save my credentials using the same mechanism that IE, for example, uses to save and re-fill passwords in web forms.
Ideally, I'd like a re-usable component for entering, saving, and retrieving credentials(including the UI with an optional "save creds" checkbox) so that my app can simply do something like this (in pseudocode):
// retrieve any saved credentials from some secure place
Credentials creds = GetCreds(some parameters go here);
// if none stored, then show the user an "enter and optionally save credentials" dialog
if (creds == null)
creds = GetCredsDialog(some parameters go here);
// POST to the authentication page
if (creds != null)
{
string authUrl = "https://somehost/login/";
string postDataPattern = "post data pattern here";
// use SecureString here instead?
string postData = string.Format (postDataPattern, HttpUtility.HtmlEncode(creds.Username), HttpUtility.HtmlEncode(creds.Password));
WebClient wc = new WebClient();
string html = wc.UploadString (authUrl, "POST", postData);
// TODO: if html indicates login failure, clear stored credentials
// and ask for new creds. then retry.
}
Essentially I want to shift the burden of securely storing creds from my app to Windows, under the assumption that the Windows guys will be better at this than I will be. :-)
I'm not looking for iron-clad security here, just something comparable to what IE is using to secure my other stored passwords for other websites. I just don't want to keep plain text passwords in my code!
Of course, the right solution here is to work with the IT department to get them to get a real authentication scheme for Wireless, but in the meantime I'm on my own.
A .NET solution would be preferable, but a Win32 solution would be OK too-- I could simply port the app to C++ without much trouble.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要存储凭据,请使用 ProtectedData System.Security.dll 中的类。
通过传递
DataProtectionScope.CurrentUser
,其他用户将无法解密该数据。编辑:对于该对话框,您可以使用 CredUIPromptForCredentials API 函数
请参阅此处了解.Net 包装器。
To store the credentials, use the ProtectedData class in System.Security.dll.
By passing
DataProtectionScope.CurrentUser
, no other user will be able to decrypt the data.EDIT: For the dialog, you can use the CredUIPromptForCredentials API function
See here for a .Net wrapper.