AcceptSecurityContext (Digest) 函数

AcceptSecurityContext (Digest) 函数允许传输应用程序的服务器组件在服务器与远程客户端之间建立安全上下文。 远程客户端使用 InitializeSecurityContext (Digest) 函数来启动建立安全上下文的流程。 服务器可能需要来自远程客户端的一个或多个回复令牌才能完成安全上下文的建立。

语法

SECURITY_STATUS SEC_Entry AcceptSecurityContext(
  _In_opt_    PCredHandle    phCredential,
  _Inout_opt_ PCtxtHandle    phContext,
  _In_opt_    PSecBufferDesc pInput,
  _In_        ULONG          fContextReq,
  _In_        ULONG          TargetDataRep,
  _Inout_opt_ PCtxtHandle    phNewContext,
  _Inout_opt_ PSecBufferDesc pOutput,
  _Out_       PULONG         pfContextAttr,
  _Out_opt_   PTimeStamp     ptsExpiry
);

参数

phCredential [in, optional]

服务器凭据的句柄。 服务器使用 SECPKG_CRED_INBOUND 或 SECPKG_CRED_BOTH 标志集来调用 AcquireCredentialsHandle (Digest) 函数,从而检索此句柄。

phContext [in, out, optional]

指向 CtxtHandle 结构的指针。 第一次调用 AcceptSecurityContext (Digest)时,该指针为 NULL。 在后续调用中,phContext 则为首次调用在 phNewContext 参数中返回的已部分形成的上下文的句柄。

警告

请勿在对 AcceptSecurityContext (Digest) 的并发调用中使用同一上下文句柄。 安全服务提供商中的 API 实现的线程不安全。

pInput [in, optional]

由客户端调用 InitializeSecurityContext (Digest) 所生成的 SecBufferDesc 结构的指针,而该结构包含输入缓冲区描述符。

下表显示了 Digest HTTP 的缓冲区配置。 第一个缓冲区的类型必须为 SECBUFFER_TOKEN,其余缓冲区的类型则必须为 SECBUFFER_PKG_PARAMS。 SASL 仅需缓冲零。

缓冲区编号/缓冲区类型 含义
0
SECBUFFER_TOKEN
第一次调用时为零,而第二次调用时则为从客户端收到的质询响应。
1
SECBUFFER_PKG_PARAMS
方法。 字符为请求行中的线路格式。 US ASCII 单字节字符。
2
SECBUFFER_PKG_PARAMS
保留。
3
SECBUFFER_PKG_PARAMS
HEntity。 H(实体正文)的十六进制表示形式。 US ASCII 单字节字符。
4
SECBUFFER_PKG_PARAMS
领域。 质询的领域字符串。 必须能以 US ASCII 来表示的 Unicode 字符串。
5
SECBUFFER_CHANNEL_BINDINGS | SECBUFFER_READONLY
包含通道绑定令牌值。
Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:不支持此值。

fContextReq [in]

位标志,可用于指定服务器建立上下文所需的属性。 可使用逐位 OR 运算来组合位标志。 此参数可使用以下一个或多个值。

含义
ASC_REQ_ALLOCATE_MEMORY Digest 会为你分配输出缓冲区。 使用完输出缓冲区后,通过调用 FreeContextBuffer 函数释放它们。
ASC_REQ_ALLOW_MISSING_BINDINGS 表示 Digest 不需要内部通道和外部通道的通道绑定。 当针对终结点通道绑定的支持处于未知状态时,此值可用于实现向后兼容性。
此值与 ASC_REQ_PROXY_BINDINGS 互斥。
Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:不支持此值。
ASC_REQ_CONFIDENTIALITY 加密和解密消息。
Digest SSP 仅为 SASL 支持此标志。
ASC_REQ_PROXY_BINDINGS 表示 Digest 需要通道绑定。
此值与 ASC_REQ_ALLOW_MISSING_BINDINGS 互斥。
Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:不支持此值。
ASC_REQ_CONNECTION 安全上下文不会处理格式化消息。
ASC_REQ_EXTENDED_ERROR 发生错误时,将通知远程方。
ASC_REQ_HTTP (0x10000000) 对 HTTP 使用摘要。 省略此标志可使用 Digest 以作为 SASL 机制。
ASC_REQ_INTEGRITY 对消息进行签名并验证签名。
ASC_REQ_REPLAY_DETECT 检测重播的数据包。
ASC_REQ_SEQUENCE_DETECT 检测按顺序接收的消息。

有关可能的属性标志及其含义,请参阅上下文要求。 用于此参数的标志会以 ASC_REQ 作为前缀,例如 ASC_REQ_DELEGATE。

客户端可能不支持请求的属性。 有关详细信息,请参阅 pfContextAttr 参数。

TargetDataRep [in]

目标上的数据表示形式,例如字节顺序。 此参数可以是 SECURITY_NATIVE_DREP 或 SECURITY_NETWORK_DREP。

此参数不与 Digest SSP 一起使用。 使用 Digest SSP 时,请为此参数指定零。

phNewContext [in, out, optional]

指向 CtxtHandle 结构的指针。 首次调用 AcceptSecurityContext (Digest)时,该指针会接收新的上下文句柄。 在后续调用中,phNewContext 可与 phContext 参数中指定的句柄相同。 phNewContext 不应该是 NULL

pOutput [in, out, optional]

包含输出缓冲区描述符的 SecBufferDesc 结构的指针。 此缓冲区会发送到客户端,以便输入到对 InitializeSecurityContext (Digest) 的其他调用中。 即使此函数返回 SEC_E_OK,也可能会生成输出缓冲区。 生成的所有缓冲区均须发送回客户端应用程序。

pfContextAttr [out]

某一变量的指针,而该变量可接收一组位标志,同时这些标志表示已建立上下文的属性。 有关各种属性的说明,请参阅上下文要求。 用于此参数的标志会以 ASC_RET 作为前缀,例如 ASC_RET_DELEGATE。

在最终函数调用成功返回之前,不要检查与安全性相关的属性。 与安全性无关的属性标志(如 ASC_RET_ALLOCATED_MEMORY 标志)可在最终返回之前进行检查。

ptsTimeStamp [out, optional]

指向接收上下文到期时间的 TimeStamp 结构的指针。 我们建议安全包始终以本地时间返回此值。

此参数应设为恒定最长时间。 对于 Digest 安全上下文或凭据或是使用 Digest SSP 时,没有过期时间。

注意

在上次调用身份验证流程结束之前,上下文的过期时间可能不正确,因为在协商的后续阶段会提供更多信息。 因此,ptsTimeStamp 必须一直为 NULL,直到对此函数的最后一次调用结束。

返回值

此函数将返回下列值之一:

返回代码 + 值 说明
SEC_E_INSUFFICIENT_MEMORY
0x80090300L
此函数失败。 没有足够的内存可用于完成请求的操作。
SEC_E_INTERNAL_ERROR
0x80090304L
此函数失败。 出现未映射到 SSPI 错误代码的错误。
SEC_E_INVALID_HANDLE
0x80100003L
此函数失败。 传递到函数的句柄无效。
SEC_E_INVALID_TOKEN
0x80090308L
此函数失败。 传递给函数的令牌无效。
SEC_E_LOGON_DENIED
0x8009030CL
登录失败。
SEC_E_NO_AUTHENTICATING_AUTHORITY
0x80090311L
此函数失败。 无法联系任何机构进行身份验证。 这可能是由以下情况造成的:
-身份验证方的域名不正确。
-域不可用。
-信任关系已失败。
SEC_E_NO_CREDENTIALS
0x8009030EL
此函数失败。 phCredential 参数中指定的凭据句柄无效。
SEC_E_OK
0x00000000L
函数成功。 已接受从客户端接收的安全上下文。 如果此函数生成了输出令牌,则须将此令牌发送到客户端进程。
SEC_E_SECURITY_QOS_FAILED
0x80090332L
此函数失败。 在 fContextReq 参数中指定的上下文属性标志无效。
SEC_I_COMPLETE_AND_CONTINUE
0x00090314L
函数成功。 服务器必须调用 CompleteAuthToken 并将输出令牌传递给客户端。 然后,服务器需等待来自客户端的返回令牌,然后再次调用 AcceptSecurityContext (Digest)
SEC_I_COMPLETE_NEEDED
0x00090313L
函数成功。 服务器必须完成从客户端生成消息,然后再调用 CompleteAuthToken 函数。
SEC_I_CONTINUE_NEEDED
0x00090312L
函数成功。 服务器必须将输出令牌发送到客户端,并等待返回的令牌。 返回的令牌应在 pInput 中传递,以便再次调用 AcceptSecurityContext (Digest)
STATUS_LOGON_FAILURE
0xC000006DL
此函数失败。 在建立指定的上下文后调用了 AcceptSecurityContext (Digest) 函数。
SEC_E_BAD_BINDINGS
0x80090346L
此函数失败。 未满足通道绑定策略。

注解

AcceptSecurityContext (Digest) 函数是与 InitializeSecurityContext (Digest) 函数相对应的服务器。

当服务器从客户端接收请求时,服务器会使用 fContextReq 参数来指定对会话的要求。 如此一来,服务器便可指定客户端必须使用机密或已完成完整性检查的会话,同时它可拒绝无法满足该要求的客户端。 或者,服务器也可不做任何要求,且无论客户端可提供或需要什么,均会在 pfContextAttr 参数中返回。

对于支持多回合身份验证(例如,相互身份验证)的包,调用顺序如下所示:

  1. 客户端将令牌传输到服务器。
  2. 服务器首次调用 AcceptSecurityContext (Digest),从而生成一个回复令牌,然后将其发送到客户端。
  3. 客户端接收此令牌并将其传递给 InitializeSecurityContext (Digest)。 如果 InitializeSecurityContext (Digest) 返回 SEC_E_OK,则已完成相互身份验证,且可开始安全会话。 如果 InitializeSecurityContext (Digest) 返回错误代码,相互身份验证协商则已结束。 否则,InitializeSecurityContext (Digest) 返回的安全令牌将发送到客户端,并重复执行步骤 2 和 3。
  4. 请勿在对 AcceptSecurityContext (Digest) 的并发调用中使用 phContext 值。 安全提供商中实现的线程不安全。

fContextReqpfContextAttr 参数是用于表示各种上下文属性的位掩码。 有关各种属性的说明,请参阅上下文要求

注意

虽然 pfContextAttr 参数在任意成功的返回时均有效,但它仅会在有检查与上下文的安全方面相关的标志的情况下的最后一次成功返回时有效。 中间返回可以设置 ISC_RET_ALLOCATED_MEMORY 标志。

调用方负责确定最终上下文属性是否足够。 例如,如果要求建立机密性(加密)但无法成功完成,某些应用程序则可能会选择立即关闭此连接。 如果无法建立安全上下文,服务器则须通过调用 DeleteSecurityContext 函数来释放已部分创建的上下文。 有关何时调用 DeleteSecurityContext 函数的信息,请参阅 DeleteSecurityContext

建立安全上下文后,服务器应用程序可使用 QuerySecurityContextToken 函数来检索客户端证书所映射到的用户帐户的句柄。 此外,服务器还可使用 ImpersonateSecurityContext 函数来模拟用户。

要求

要求
最低受支持的客户端 Windows XP [仅限桌面应用]
最低受支持的服务器 Windows Server 2003 [仅限桌面应用]
标头 Sspi.h(包括 Security.h)
Secur32.lib
DLL Secur32.dll

另请参阅

SSPI 函数

DeleteSecurityContext

InitializeSecurityContext(摘要)