您如何获取当前登录用户的凭据(NetworkCredential)?
Posted
技术标签:
【中文标题】您如何获取当前登录用户的凭据(NetworkCredential)?【英文标题】:How do you get credentials (NetworkCredential) of currently logged in user? 【发布时间】:2010-02-23 16:08:51 【问题描述】:我正在编写一些代码来利用第 3 方组件,当我开始使用它时,我需要提供一个实现 ICredentials 的对象。
如果我写下面...
var credential = new NetworkCredential("MyUsername", "MyPassword");
...并通过“凭据”,这很好。但我想传递当前用户的凭据(它是 Windows 服务,因此以指定用户身份运行)。
我尝试了以下两种方法,但似乎都不起作用(或返回任何东西):
NetworkCredential credential = System.Net.CredentialCache.DefaultCredentials;
NetworkCredential credential = CredentialCache.DefaultNetworkCredentials;
任何人都可以建议如何获取一个适当的对象,该对象代表服务在其下运行的用户名的凭据?
谢谢
【问题讨论】:
我在 WCF 客户端场景中遇到了同样的问题,请参阅此线程 ***.com/questions/3166150/… 见***.com/questions/3166150/… 你可能需要您是否尝试过 WindowsIdentity.GetCurrent()?
你也可以看看这个例子...http://www.codeproject.com/KB/vb/Windows_Service.aspx
【讨论】:
"你试过 WindowsIdentity.GetCurrent 吗?"是的,它似乎没有帮助 - 即使您将结果传递给 Impersonate。该示例似乎是获取当前用户名的一种有趣(?)方式。谢谢【参考方案2】:你需要做模拟,例如:
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
//Insert your code that runs under the security context of the authenticating user here.
impersonationContext.Undo();
http://support.microsoft.com/kb/306158
或者你可以使用 web.config:
<identity impersonate="true" />
【讨论】:
谢谢,但我是作为 Windows 服务运行的,而不是作为 ASP 网页运行的。到目前为止,我发现的所有建议都与 ASP 有关。我已经尝试过模拟,但它没有帮助/工作(在这种情况下)。我很惊讶似乎没有办法获取当前用户(毕竟是登录的)的凭据,而是必须编写一些 hacky 方法来存储用户的用户名和密码。呸! (谢谢你的建议)【参考方案3】:理想的安全情况是登录用户的密码不会存储在内存中的任何位置。它也不存储在磁盘上的任何位置。它仅作为哈希值存在,可与人类输入的字符串进行比较。明文存储密码本质上是一种安全风险,应尽可能避免。
鉴于此原则,操作系统中没有任何部分连你的用户密码都是明文的,更不用说愿意给你了。
【讨论】:
这里似乎有些混乱。我从来没有问过如何获取密码。我问,鉴于我有一个必须“登录”的进程(因为需要一个更好的术语),它正在使用有效的凭据运行。我想将它们传递给第 3 方组件——我不需要知道它们是什么。我知道我创建了一组新的凭据(假设我知道密码)它有效,但我找不到获取(并传递)当前凭据的方法。 这正是我所描述的情况。为了获得当前的凭证,他们必须在某处被某些软件持有。这会降低系统的安全性。模拟应该允许您希望调用的任何组件以登录用户的身份act,而不需要实际的凭据。我不知道你为什么对我投了反对票,而不是对这篇文章的第一个回答,这篇文章对安全做出了同样的声明(“事实上,这是一种不安全的做法”)。 拥有一个代表当前进程凭据的签名令牌(被允许做一些事情,包括作为进程与其他程序对话)与拥有凭据不同。由于一个进程可以通过多种方式与另一个进程通信,因此这是可配置的。将此令牌作为参数传递是指定我们要“以我自己”身份进行身份验证而不使用某些新凭据的预期方式。这就是我们想要做的。 NetworkCredential BY DEFINITION 需要用户名和密码。可以想象,可能有一个不同的 iCredential 没有,并且您可以将其提供给您的 3rd 方组件。但我找不到。【参考方案4】:不幸的是,您必须像这样与 WMI 互操作:
http://www.codeproject.com/Articles/28161/Using-WMI-to-manipulate-services-Install-Uninstall
您要查询的值是 StartName,它将评估为类似于“NT Authority\NetworkService”(或您正在使用的任何内容)的值。如果您将本文的第二部分与第一部分混搭起来,应该很简单。
【讨论】:
【参考方案5】:您是否尝试在应用程序启动时为 appdomain 设置 principalpolicy?
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
在通过线程访问当前主体对象之前设置此值可确保在此对象中使用 windows 标识。
edit - 我很确定这适用于 DefaultNetworkCredentials。我用它通过 Windows 窗体应用程序访问具有 Windows 身份验证的 Web 服务。
【讨论】:
【参考方案6】:如果您只想在当前用户添加动词时运行进程:
"runas " & Environment.UserName
如果您想以管理员身份运行该进程,只需写"runas"
在 vb.net 中
Dim ps As New System.Diagnostics.ProcessStartInfo("filepath", "arguments")
ps.Verb = "runas" 'run as admin
'ps.Verb = "runas " & Environment.UserName'run as current user, by default
Dim p As System.Diagnostics.Process = System.Diagnostics.Process.Start(ps)
如果你想得到当前用户的密码,你不能,实际上这是一种不安全的做法。 您的服务需要什么权利以及出于什么目的来获取我的 Windows 密码机密? 例如,就像将手机的 PIN 码提供给 whatsapp
【讨论】:
这没有回答问题。以上是关于您如何获取当前登录用户的凭据(NetworkCredential)?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 asp.net 中使用 Windows 身份验证获取用户名?