您如何获取当前登录用户的凭据(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/… 你可能需要 CredentialCache 应该可以工作。您可以检查 WindowsIdentity.GetCurrent 并查看确实有用户登录吗? 嗨,WindowsIdentity.GetCurrent 返回一个 WindowsIdentity 对象(使用当前用户名),但 System.Net.CredentialCache.DefaultCredentials 和 DefaultNetworkCredentials 都返回空 ICredentials 对象。 您的第 3 方组件是什么?它是否支持 NTLM 或 Kerberos 之类的东西?答案不会是尝试读取用户的密码——那将是一个明显的安全漏洞。您需要找出一种不同的身份验证方式。 【参考方案1】:

您是否尝试过 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 " &amp; 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)?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取当前登录用户的 UPN(用户主体名称)?

如何在 asp.net 中使用 Windows 身份验证获取用户名?

asp.net Web 应用程序返回 IIS 信息而不是当前用户凭据

XML-RPC:如何使过程调用可以访问登录凭据?

如何获取其他系统登录的用户信息

用户如何在ldap服务器中创建用户后登录?