Windows身份验证令牌C ++

时间:2012-02-21 15:28:56

标签: c++ windows-authentication

简单地说:我可以在C ++中生成某种文本信息 - 用户令牌,会话令牌,访问令牌(?) - 当前登录的Windows用户,然后在某处验证此文本信息(验证用户) else(域中的不同计算机)?

passing string token

我有两台电脑。在第一个用户应该能够通过客户端应用程序连接到我在第二台计算机上运行的服务器应用程序。他必须使用Windows身份验证,因此服务器将使用他的Windows组来获取一些信息 - 没有用户名/密码发送。我的想法是(不知道是否可能)客户端计算机/进程知道当前用户,因此它将获取用户的访问令牌或类似的东西,将其传递给服务器(作为字符串参数),服务器将验证这个令牌字符串是有效的,将获取该Windows用户及其组的名称以进行下一步操作,这就是我需要的。

这可能只是从客户端发送到服务器的一个信息(此访问令牌/会话令牌或如何调用它)? (http服务器,我只想用一个登录请求发送该字符串令牌,该登录请求当前用于其他专有的身份验证方式,如果可能的话,不进行握手/协商或类似的事情)。我正在使用C ++。

我目前发现了两种方式(可能是不怎么做的方式;)

1)像OpenProcessToken,GetTokenInformation这样的函数 - 这让我可以访问访问令牌,但它只是Handle,我可能只在我的进程中使用它,不可能将它发送到其他地方......

2)像AcquireCredentialsHandle,InitializeSecurityContext,AcceptSecurityContext这样的函数 - 今天我花了很多时间 - 我使用这些函数制作了一些测试应用程序,只是在一个进程中运行,我目前还不能确定它应该如何制作通过两台计算机之间的“文本”通信,但这并不重要 - 似乎必须进行更多轮次 - 客户端创建一些东西(上下文,凭证,令牌......),将其发送到服务器,服务器做某事,回复客户端,客户端获取结果等。我是否可以通过创建“会话令牌”并发送它(例如使用domain @ username,如果有必要)而不再返回其他信息来实现它?

感谢任何帮助,谢谢!

编辑:基于下面的第一条评论,我似乎需要澄清这一点: 想象一下,用户运行Web浏览器并在其他地方连接到我的服务器应用程序。他想发送“CONNECT”和“DO_STUFF”之类的命令。仅当此用户可以先连接时,服务器应用才会执行do_stuff。但是,例如,只有当用户是某些Windows组的成员(使用的是Windows身份验证,而不是某些专有用户和密码)时,此用户才能进行连接。因此,服务器必须检查该用户是否是该组的有效成员。但服务器只能根据用户提供的文本信息来做到这一点。好吧,用户可以通过服务器应用程序发送他的Windows用户名和密码进行身份验证(应该由C ++函数LogonUser或其他任何东西完成),但这很危险,我不希望用户在某处输入他的用户名和密码,我只想要他“点击登录按钮”,C ++将关心其余的,因为它可以检查他当前的会话数据,他已经登录。我的想法只是提供用户名和某种字符串用户令牌(会话令牌,访问令牌,我不知道确切的术语)将由用户客户端应用程序生成(使用Kerberos,NTLM,我不知道),服务器将收到此字符串信息,它将检查此令牌以验证“这是有效的有效的Windows用户的标记,这里是他所属的组“...类似的东西。希望这个解释有所帮助。

1 个答案:

答案 0 :(得分:3)

像AcquireCredentialsHandle,InitializeSecurityContext,AcceptSecurityContext等类似的函数都是这里的解决方案。

检查http://msdn.microsoft.com/en-us/library/ms973911.aspx#remsspi_topic3

如果你只是想验证用户,NTLM没问题,但是你需要交换多条消息,不能像我原来需要的那样只需一步完成(需要:协商,挑战,响应),所以你是实际发送3条短信并按上述功能处理。

如果要委派(服务器可以充当客户端 - 模拟 - 甚至将权限委托给其他进程),则需要使用Kerberos(需要Active Directory)。一切都必须在一个领域完成。这可以通过基于下面的图像从客户端向服务器发送更少的消息来实现,因为权限更多,但我没有测试过这种情况。

NTLM and Kerberos handshake http://i.msdn.microsoft.com/dynimg/IC10253.gif