身份验证 (BITS)

BITS 支持基本身份验证、Passport 身份验证和多个质询/响应身份验证方案。 如果服务器或代理需要用户身份验证,请使用 IBackgroundCopyJob2::SetCredentials 函数指定用户的凭据。 BITS 使用 CryptoAPI 来保护凭据。

若要设置基本身份验证的凭据,请使用 SetCredentials 函数指定用户名和密码。 应仅对 https:// 受保护的安全网站使用基本身份验证;否则,用户名和密码对用户可见。

可以在 URL 中嵌入用户名和密码。 这被认为不是一个好的安全做法,并且在 RFC 3986(第 3.2.1 节)中被弃用。

对于 Passport 身份验证,BITS 仅支持显式凭据,而不支持绑定到帐户的隐式凭据。

对于质询/响应身份验证,BITS 模拟用户并使用 Snego 来确定要使用的质询/响应身份验证,例如 NTLM 或 Kerberos 协议。 有关 BITS 支持的质询/响应方案列表,请参阅 BG_AUTH_SCHEME

如果服务器上的虚拟目录启用了匿名身份验证和另一个身份验证方案,以及 ACL 保护虚拟目录或下载文件,则 BITS 作业可能会失败。 例如,如果虚拟目录启用了匿名和集成身份验证,并且文件包含仅允许 Ben 读取文件的 ACL,则作业将失败并出现“访问被拒绝”。 发生这种情况是因为虚拟目录允许匿名访问,因此 IIS 不会显式对 Ben 进行身份验证(Ben 的凭据不用于访问文件和访问被拒绝)。

使用隐式凭据

若要将用户的隐式(登录)凭据用于 NTLM 或 Kerberos 身份验证,请调用 IBackgroundCopyJob2::SetCredentials 方法,并将 BG_BASIC_CREDENTIALS 结构的 UserNamePassword 成员设置为 NULL。 如果为代理指定隐式凭据,则 BITS 还将使用隐式凭据进行身份验证,除非指定显式服务器凭据。

有关服务的其他信息,请参阅服务帐户和 BITS

还可以更改 LMCompatibilityLevelUseLMCompat 注册表值;但是,仅当现有应用程序无法更改以调用SetCredentials 方法时,才应更改这些值。

如果 LMCompatibilityLevel 注册表值是两个或更大,并且尚未调用 SetCredentials 方法,则 BITS 将使用隐式凭据进行身份验证。 LMCompatibilityLevel 注册表值的完整路径是 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\LSA\LmCompatibilityLevel

请注意,更改 LMCompatibilityLevel 注册表值可能会影响计算机上运行的其他应用程序和服务。

如果设置 LMCompatibilityLevel 注册表值有问题,则可以在 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\BITS 下创建 UseLMCompat 注册表值。 注册表值为 DWORD。 下表列出了 UseLMCompat 的可能值:

说明
0 每当服务器提示输入 NTLM 或 Kerberos 凭据时,BITS 都会发送隐式凭据。
1 仅当客户端计算机的 LMCompatibilityLevel 注册表值大于或等于 2 时,BITS 才会发送隐式凭据。
2 仅当应用程序调用 SetCredentials 方法时,BITS 才会发送隐式凭据。

如果注册表值不存在,BITS 将为 UseLMCompat 注册表值使用默认值“2”。

使用证书进行客户端/服务器身份验证

在安全的客户端/服务器通信中,客户端和服务器可以使用数字证书相互进行身份验证。 BITS 自动支持基于证书的服务器身份验证来保护 HTTP 传输。 若要提供相互身份验证所需的客户端证书,请调用IBackgroundCopyJobHttpOptions::SetClientCertificateByIDIBackgroundCopyJobHttpOptions::SetClientCertificateByName 方法。

当网站接受但不需要 SSL 客户端证书,并且 BITS 作业未指定客户端证书时,该作业将失败,并出现 ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED (0x80072f0c)。

如何处理需要用户特定设置的经过身份验证的代理方案

如果在需要代理身份验证的环境中使用 BITS,同时在计算机的网络域中作为没有可用 NTLM 或 Kerberos 凭据的帐户运行,则必须采取额外步骤,使用在域中具有凭据的另一个用户帐户的凭据进行正确身份验证。 当 BITS 代码作为系统服务(如 LocalService、NetworkService 或 LocalSystem)运行时,这是一种典型的情况,因为这些帐户没有可用的 NTLM 或 Kerberos 凭据。

设置网络帮助程序令牌 (BG_TOKEN_NETWORK) 时,BITS 中使用的代理检测逻辑执行以下操作:

之后,帮助程序令牌模拟用于整个代理或服务器身份验证。

从 Windows 10 版本 1809 开始(10.0;内部版本 17763),使用用户特定的凭据简化了经过身份验证的代理方案。

  1. 使用 BG_AUTH_SCHEME_NEGOTIATE 调用 BITS 作业的 SetCredentials 方法,其中 UserName 设置为 NULLPassword 设置为 NULLTarget 设置为 BG_AUTH_TARGET_PROXY。 这会导致用户帐户的隐式凭据用于使用代理服务器进行 NTLM 和 Kerberos 身份验证。
  2. 使用 BG_JOB_PROXY_USAGE_PRECONFIG 调用 IBackgroundCopyJob::SetProxySettings
  3. IBitsTokenOptions 的 QueryInterface。
  4. 模拟用于 NTLM/Kerberos 凭据的用户帐户。
  5. 调用 SetHelperToken
  6. 使用 BG_TOKEN_NETWORK 调用 SetHelperTokenFlags
  7. 还原模拟。
  8. 继续作业设置。
  9. 对作业调用 Resume

在 Windows 10 版本 1809(10.0;内部版本 17763)之前,正确的用户标识(帮助程序令牌的标识)用于基于网络的代理检测 (WPAD) 和代理身份验证,但本地代理设置的实际检测始终使用作业所有者的令牌完成,即使配置了帮助程序令牌也是如此。 若要解决此问题,可以按照以下步骤操作。

  1. 模拟用于 NTLM/Kerberos 凭据的用户帐户。
  2. 通过调用 WinHttpGetIEProxyConfigForCurrentUser 检索用户帐户的 IE 代理设置。
  3. 还原模拟。
  4. 使用 BG_AUTH_SCHEME_NEGOTIATE 调用 BITS 作业的 SetCredentials 方法,其中 UserName 设置为 NULLPassword 设置为 NULLTarget 设置为 BG_AUTH_TARGET_PROXY。 这会导致用户帐户的隐式凭据用于使用代理服务器进行 NTLM 和 Kerberos 身份验证。
  5. 如果步骤 2 生成了任何用户特定的代理设置(即 lpszProxylpszProxyBypass,而不是 NULL),请使用 SetProxySettingsBG_JOB_PROXY_USAGE_OVERRIDE 手动设置相应的作业设置。
  6. 如果步骤 2 未生成任何特定于用户的代理设置,请使用 BG_JOB_USAGE_PRECONFIG 调用 SetProxySettings
  7. IBitsTokenOptions 的 QueryInterface。
  8. 再次模拟用户帐户。
  9. 调用 SetHelperToken
  10. 使用 BG_TOKEN_NETWORK 调用 SetHelperTokenFlags
  11. 还原模拟。
  12. 继续作业设置。
  13. 对作业调用 Resume