【问题标题】:Check user credential against a workgroup server根据工作组服务器检查用户凭据
【发布时间】:2012-11-13 19:43:50
【问题描述】:

我的应用程序将在客户端台式计算机上的 LAN 上使用。在这个 LAN 中,有一个专用的 Windows 2k 服务器。没有广告。

用户必须填写服务器的用户帐户信息,以便应用程序可以使用此帐户进行一些远程操作(映射网络驱动器)

如何检查此服务器的用户凭据?

在映射驱动程序时,如果用户帐户身份验证不正确,我会遇到错误,但我想在尝试映射之前获得此信息。

类似于 LogonUser API 函数,但在远程计算机上工作。

谢谢,

【问题讨论】:

    标签: delphi winapi windows-server-2000


    【解决方案1】:

    您可以将WNetUseConnection 函数与CONNECT_INTERACTIVECONNECT_PROMPT 标志一起使用。当您输入正确的凭据时,这将与空的用户 ID 和密码参数一起调用凭据对话框并连接到网络资源:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      BufferSize: DWORD;
      ResultFlag: DWORD;
      NetResource: TNetResource;
    begin
      NetResource.dwType := RESOURCETYPE_DISK;
      NetResource.lpLocalName := nil;
      NetResource.lpRemoteName := '\\MySuperSecret\Place';
      NetResource.lpProvider := nil;
      if WNetUseConnection(Handle, NetResource, nil, nil, CONNECT_INTERACTIVE or
        CONNECT_PROMPT, nil, BufferSize, ResultFlag) = NO_ERROR
      then
        ShowMessage('Connected!');
    end;
    

    要在不提示输入凭据的情况下连接到网络资源,请删除上面指定的标志,如下面的函数所示,连接成功时应返回 True,失败时返回 False。参数说明如下:

    • RemoteName(字符串)- 远程网络名称
    • UserName(字符串)- 用于连接网络资源的用户名
    • 密码(字符串)- 用于连接网络资源的密码

    function TryConnect(const RemoteName, UserName, Password: string): Boolean;
    var
      BufferSize: DWORD;
      ResultFlag: DWORD;
      NetResource: TNetResource;
    begin
      NetResource.dwType := RESOURCETYPE_DISK;
      NetResource.lpLocalName := nil;
      NetResource.lpRemoteName := PChar(RemoteName);
      NetResource.lpProvider := nil;
      Result := WNetUseConnection(0, NetResource, PChar(UserName), PChar(Password),
        0, nil, BufferSize, ResultFlag) = NO_ERROR;
    end;
    

    【讨论】:

    • 谢谢,我知道这种工作方式。问题是我的应用程序是一种设置应用程序,在开始时会询问凭据,然后在几个设置样式页面之后,它会尝试使用提供的凭据静默映射网络资源。我正在寻找一种在开始时检查凭据的方法
    • 然后您可以尝试删除这些标志。第一个,CONNECT_INTERACTIVE 指定操作系统可以与用户交互以进行身份​​验证,所以现在它应该满足您的需求。
    • 感谢您的意见,我已经实施了您的解决方案
    • 最后一件事:我发现在 Result := True 的情况下,我必须执行 WNetCancelConnection2(PChar(FRemoteLocation), 0, True);以避免不良结果。万一第一次尝试ok,然后我拔网线重试,结果还是真见:stackoverflow.com/questions/2296918/…
    【解决方案2】:

    我使用单位 SSPIValidatePassword.pas 来自http://www.michael-puff.de/Programmierung/Delphi/Units/ 这对我来说是正确的。该单元中唯一导出的函数 SSPLogonUser 返回 true 或 false....

    【讨论】:

    • 谢谢,但我想不出办法让它工作。我尝试了其他实现(delphi-kb.blogspot.fr/2010/07/…),但我无法使其与域控制器或工作组服务器一起工作
    • +1 用于 SSPI 解决方案!正如微软建议的那样,SSPI 是在 Windows 下验证凭据的首选方式:support.microsoft.com/kb/180548;也不错的阅读:stackoverflow.com/questions/7111618/…
    • @Fred,SSPI 实现是基于 Ansi,但在 Delphi >= 2009 中“字符串”类型是 unicode - 可能这就是代码不起作用的原因?
    • @Fred,实际上 SSPIValidatePassword.pas 在 Delphi 7 下按预期编译和运行。所以它是关于 Delphi >= 2009 中的 PAnsiChar / PWideChar 和 unicode 字符串类型
    • 感谢您的评论,我同意您的观点,即使用 SSPI 是正确的方法,但我找不到使它起作用的方法。我在D7下编译了一个测试样本。在测试网络上,我在同一个工作组中有 2 台电脑、一个 XP 客户端和一个 2k 服务器。在服务器上,我有一个管理员帐户。使用此测试示例,它始终返回 false,但使用相同的凭据,我可以安装网络驱动器或连接到服务器
    猜你喜欢
    • 2011-11-28
    • 2017-05-12
    • 2021-02-06
    • 2013-11-24
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多