背景:
- 计算机
mycomputer正在运行 Windows 10 并已加入域mydomain.com。 - 用户使用本地帐户登录
mycomputer\localuser。mycomputer - 用户也知道域帐户的密码
mydomain\domainuser。 - 服务主体名称
myprotocol/domainuser在 Active Directory 中注册并映射到域帐户mydomain\domainuser。 - 不允许本地用户
mycomputer\localuser以mydomain\domainuser.
用户希望在本地帐户下启动服务器进程,然后使用域帐户来验证与 Kerberos 的传入连接。
我想编写该服务器的代码。
客户端代码:
客户端代码很简单,由一个调用组成,AcquireCredentialsHandle然后调用InitializeSecurityContext:
AcquireCredentialsHandle(
nullptr,
"Kerberos",
SECPKG_CRED_OUTBOUND,
nullptr,
nullptr,
nullptr,
nullptr,
&credentials,
&lifetime);
InitializeSecurityContext(
&credentials,
nullptr,
"myprotocol/myport",
ISC_REQ_CONFIDENTIALITY,
0,
SECURITY_NATIVE_DREP,
nullptr,
0,
&securityContext,
&outBufferArray,
&contextAttributes,
&lifetime);
请注意代码片段中字符串的简化用法。必须处理的现实wchar_t和const正确性有些丑陋。
另请注意,如果适当的凭据存储在控制面板的凭据管理器中,则此代码在由本地用户启动时有效 - 即使用主机名domainuser(原文如此。)
服务器代码:
我已经有一个代码可以在进程启动时工作mydomain\domainuser:
AcquireCredentialsHandle(
nullptr,
"Kerberos",
SECPKG_CRED_INBOUND,
nullptr,
nullptr,
nullptr,
nullptr,
&credentials,
&lifetime);
AcceptSecurityContext(
&credentials,
nullptr,
&inBufferArray,
attribs,
SECURITY_NATIVE_DREP,
&securityContext,
nullptr,
&attribs,
&lifetime);
但是,当服务器启动时mycomputer\localuser,调用AcquireCredentialsHandle失败并出现代码SEC_E_NO_CREDENTIALS。
- 我尝试将该调用的第一个参数修改为
"myprotocol/domainuser","domainuser"或"mydomain\domainuser"什至"domainuser@mydomain.com". mycomputer我尝试使用主机名甚至在控制面板的凭据管理器中添加所需的凭据domainuser。
mydomain\domainuser在由 启动的进程中,我可以做些什么来获取凭据句柄mycomputer\localuser?
编译代码片段:
#include <string>
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define SECURITY_WIN32
#include <sspi.h>//Requires linking on Secur32.lib
int main(){
CredHandle credentials;
TimeStamp lifetime;
std::string package="Kerberos";
std::string principal="myprotocol/domainuser";
auto res=AcquireCredentialsHandle(
principal.data(),
package.data(),
SECPKG_CRED_INBOUND,
nullptr,
nullptr,
nullptr,
nullptr,
&credentials,
&lifetime);
if(res==SEC_E_OK){
std::printf("Success\n");
FreeCredentialsHandle(&credentials);
return 0;}
else{
std::printf("Failure\n");
return res;}}