如何以编程方式与winlogon进行交互?

时间:2017-12-30 23:17:37

标签: c# winapi winlogon credential-providers

我有一个Windows服务,我想使用帐户用户名和密码以编程方式解锁工作站。

本文https://technet.microsoft.com/en-us/library/dn751047(v=ws.11).aspx解释了Windows上的登录身份验证工作流程,如下图所示:  authentication workflow

如上所述,在步骤5中,用户将凭证输入到登录UI中。我想要实现的是让Windows服务输入凭据并让winlogon执行登录。

没有winlogon API来实现这一目标。如其他问题所示,使用winapi的LogonUser函数成功执行身份验证并返回一个令牌,但它不会切换到应用程序桌面,并且登录UI仍保留在屏幕上。

大多数文章和SO答案暗示了凭据提供者,但所有凭据提供者样本都需要用户与其进行交互 登录UI。

更新:我看到一些用户还没有完全理解这个问题,并提出了对我的案例无用的解决方法。我想要实现的工作流程如下:

  1. Windows服务在Windows启动(完成)时启动。
  2. 相同的Windows服务具有Web服务,并通过API(完成)接受HTTP请求。
  3. 用户通过API从其他设备(完成)向服务提供凭据。
  4. 提供的凭据用于登录工作站 4.1提供的凭证用于在锁定时解锁工作站(WinKey + L)。
  5. (可选)该服务通过API公开Windows帐户。
  6. (可选)用户可以向服务指定要用于登录的帐户。
  7. 目前,我有兴趣制作第4步和第4.1步。

6 个答案:

答案 0 :(得分:1)

不是我宽恕这样做,而是给你解决问题的方法。它不是以编程方式与WinLogon进程交互。它以编程方式解决它。

使用Windows自动登录属性。并重新启动以更改为该用户。 请注意,这确实涉及以明文形式将密码存储在注册表中。

专门设置这些regkeys

HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Winlogon \ AutoAdminLogin HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Winlogon \ DefaultUserName HKLM \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Winlogon \ DefaultPassword

*编辑*

帮助4.没有帮助4.1。除非你想重新启动解锁我怀疑。

在较早的问题https://stackoverflow.com/a/35173886/4640588

中提到了另一个听起来很有希望但值得研究的替代方案

答案 1 :(得分:1)

正在通过......但是在微软的样本中,不存在采用异步输入的凭据提供程序吗?我当然写了一个登录用户的人,无论显示什么样的图块,扫描可接受的指纹。对我来说,这意味着与LogonUI的交互只需要隐含,但也许我错过了一些东西。

但也许我不是。虽然我不怀疑意图是异步输入将来自用户在硬件上行动,就像扫描手指一样,我不记得这是一个规则。如果不是,那么您可以以提供凭证的形式提供您的编程选项,就好像它们是异步收集的 - 不是来自显然连接到计算机的设备,而是来自HTTP的侧通道,谁知道什么。

那么,您是否可以让凭据提供程序从您的服务中侦听RPC,以获取您的服务通过其旁道收集的凭据通知?或者让您的服务从您的凭据提供程序中侦听RPC,以询问可用的凭据是什么?如果一个方向被关闭,我可能不会感到惊讶 - 为了安全,甚至 - 但我认为可以使一个或其他方向起作用。

你是否应该想做这些,我不想进入。

答案 2 :(得分:0)

我为此编写了一个商业解决方案,名为SasLibEx。 SasLibEx是一个面向开发人员的库,本地支持c / c ++和delphi。

SasLibEx可以:

  • 模拟Ctrl Alt Del(安全注意序列)
  • 取消Ctrl Alt Del
  • 锁定工作站
  • 解锁工作站(无凭据)
  • 禁用Ctrl Alt Del
  • 再次启用Ctrl Alt Del
  • 取消待处理的UAC请求
  • 桌面锁定

请参阅https://www.remkoweijnen.nl/blog/tag/saslibex/

答案 3 :(得分:0)

对于我正在构建的基于硒的框架,我的要求几乎相同。简而言之,我需要在用户的Windows工作站(WinSTA0)中运行一个应用程序 - 这意味着一个用户必须在VM中登录。

我已经使用凭据管理器创建了一个项目,并使用它来实现以下工作流程:

  • 启动虚拟机,使用Powershell复制组件
  • 安装CredManager,重启VM
  • Cred manager创建一个随机用户,将其保存在数据库中
  • 使用该用户登录
  • 用户在注册表中启动了自动启动应用程序,应用程序启动了一个可以联系以启动selenium会话的Web服务器

如果我正确理解您的要求,您将需要创建一个凭据管理器,该服务器将公开要与自动登录凭据联系的服务器(http,命名管道等) - 无需在此处花时间在UI上。使用Advice实施下的ITestWindowsCredentialProvider方法启动服务器,UnAdvice停止服务器。

我建议以下内容帮助您实现目标:

  • 使用外部日志记录服务(如app-insights)来获取 反馈您的服务并简化调试
  • 使用VM作为良好做法导致Winlogon中的严重故障将导致计算机无效。
  • 在COM组件实现的所有方法的更高级别使用try catch以吞下异常以保存winlogon崩溃

此外,为了更大的图片,您必须记住所有这些进程对Windows工作站,桌面具有不同的访问权限(以及COM组件的生命周期),并以不同的用户身份运行。但我不认为这对你很重要。

您可以在此处找到基本凭据管理器代码: https://github.com/phaetto/windows-credentials-provider

答案 4 :(得分:0)

您的任务是实现凭证提供程序接口,并在您的服务接收凭证时将其轻松转发到LogonUI-请查看此answer

目标是实现可打包这些凭据的默认图块。

在某些用例中,我自己的凭据提供程序也具有自动登录/解锁行为。

答案 5 :(得分:-6)

以编程方式绕过/以用户身份登录对于网络安全而言是可怕的。

我不确定你要做什么,但是为什么不使用机器上的服务帐户来部署运行任务呢?

即使用户未在指定的时间/事件登录,您也可以将其配置为运行。如果这对你不起作用,你能描述一下你的情景吗?

相关问题