AcceptSecurityContext (常规) 函数

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

有关将此函数用于特定 安全支持提供程序 (SSP)的信息,请参阅以下主题。

主题 说明
AcceptSecurityContext (CredSSP) 允许传输应用程序的服务器组件使用凭据安全支持提供程序(CredSSP)在服务器和远程客户端之间建立 安全上下文
AcceptSecurityContext (摘要) 使传输应用程序的服务器组件能够在服务器与使用 Digest 的远程客户端之间建立 安全上下文
AcceptSecurityContext (Kerberos) 使传输应用程序的服务器组件能够在服务器与使用 Kerberos 的远程客户端之间建立 安全上下文
AcceptSecurityContext (协商) 使传输应用程序的服务器组件能够在服务器与使用 Negotiate 的远程客户端之间建立 安全上下文
AcceptSecurityContext (NTLM) 使传输应用程序的服务器组件能够在服务器与使用 NTLM 的远程客户端之间建立 安全上下文
AcceptSecurityContext (Schannel) 使传输应用程序的服务器组件能够在服务器与使用 Schannel 的远程客户端之间建立 安全上下文

语法

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]

服务器凭据的句柄。 服务器调用 AcquireCredentialsHandle(常规) 函数,并将SECPKG_CRED_INBOUND或SECPKG_CRED_BOTH标志设置为检索此句柄。

phContext[in, out]

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

警告

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

pInput[in, optional]

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

使用 Schannel SSP 时,第一个缓冲区的类型必须为SECBUFFER_TOKEN,并且包含从客户端接收的安全令牌。 第二个缓冲区的类型应为SECBUFFER_EMPTY。

在使用 Negotiate、Kerberos 或 NTLM SSP 时,除了调用 InitializeSecurityContext (常规) 函数生成的缓冲区外,还可以通过传入类型为 SECBUFFER_CHANNEL_BINDINGSSecBuffer 结构来指定通道绑定信息。 可以通过在客户端用来进行身份验证的 Schannel 上下文上调用 QueryContextAttributes (Schannel) 函数来获取通道绑定缓冲区的通道绑定信息。

fContextReq[in]

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

价值 含义
ASC_REQ_ALLOCATE_MEMORY 摘要和 Schannel 将为你分配输出缓冲区。 使用完输出缓冲区后,通过调用 FreeContextBuffer 函数释放它们。
ASC_REQ_ALLOW_MISSING_BINDINGS 表示 Digest 不需要内部通道和外部通道的通道绑定。 当针对终结点通道绑定的支持处于未知状态时,此值可用于实现向后兼容性。
此值与 ASC_REQ_PROXY_BINDINGS 互斥。
此值仅受摘要 SSP 支持。
Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:不支持此值。
ASC_REQ_CONFIDENTIALITY 加密和解密消息。
Digest SSP 仅为 SASL 支持此标志。
ASC_REQ_CONNECTION 安全上下文不会处理格式设置消息。
ASC_REQ_DELEGATE 允许服务器模拟客户端。 对 Kerberos 有效。 忽略 约束委派的此标志。
ASC_REQ_EXTENDED_ERROR 发生错误时,将通知远程方。
ASC_REQ_HTTP (0x10000000) 对 HTTP 使用摘要。 省略此标志可使用 Digest 以作为 SASL 机制。
ASC_REQ_INTEGRITY 对消息进行签名并验证签名。
Schannel 不支持此标志。
ASC_REQ_MUTUAL_AUTH 需要客户端才能提供用于客户端身份验证的证书。
此标志仅受 Schannel 支持。
ASC_REQ_PROXY_BINDINGS 表示 Digest 需要通道绑定。
此值与 ASC_REQ_ALLOW_MISSING_BINDINGS 互斥。
此值仅受摘要 SSP 支持。
Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:不支持此值。
ASC_REQ_REPLAY_DETECT 检测重播的数据包。
ASC_REQ_SEQUENCE_DETECT 检测按顺序接收的消息。
ASC_REQ_STREAM 支持面向流的连接。
此标志仅受 Schannel 支持。

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

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

TargetDataRep[in]

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

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

phNewContext[in, out, optional]

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

pOutput[in, out, optional]

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

使用 Schannel 时,在输出中,此缓冲区接收 安全上下文的令牌。 必须将此令牌发送到客户端。 该函数还可返回 SECBUFFER_EXTRA 类型的缓冲区。 此外,调用方必须传入 SECBUFFER_ALERT类型的缓冲区。 在输出中,如果生成警报,则此缓冲区包含有关该警报的信息,并且函数失败。

pfContextAttr[out]

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

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

ptsTimeStamp[out, optional]

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

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

使用 Schannel SSP 时,这是可选的。 当远程方提供用于身份验证的证书时,此参数将接收该证书的过期时间。 如果未提供证书,则返回最大时间值。

注释

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

返回值

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

返回代码/值说明
SEC_E_BAD_BINDINGS
0x80090346L
此函数失败。 未满足通道绑定策略。
SEC_E_INCOMPLETE_MESSAGE
0x80090318L
函数成功。 输入缓冲区中的数据不完整。 应用程序必须从客户端读取其他数据,并再次调用 [AcceptSecurityContext (常规)](acceptsecuritycontext--general.md)。
使用 Schannel SSP 时,可以返回此值。 有关此返回值的详细信息,请参阅 [AcceptSecurityContext (Schannel)](acceptsecuritycontext--schannel.md)。
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 参数中指定的凭据句柄无效。 使用 Digest 或 Schannel SSP 时,可以返回此值。
SEC_E_OK
0x00000000L
函数成功。 [*security context*](..已接受从客户端接收的 /secgloss/s-gly.md。 如果此函数生成了输出令牌,则须将此令牌发送到客户端进程。
SEC_E_SECURITY_QOS_FAILED
0x80090332L
此函数失败。 在 fContextReq 参数中指定的上下文属性标志无效。 使用摘要 SSP 时,可以返回此值。
SEC_E_UNSUPPORTED_FUNCTION
0x80090302L
此函数失败。 fContextReq 参数中指定了无效的上下文属性标志(ASC_REQ_DELEGATE或ASC_REQ_PROMPT_FOR_CREDS)。 使用 Schannel SSP 时,可以返回此值。
SEC_I_COMPLETE_AND_CONTINUE
0x00090314L
函数成功。 服务器必须调用 [CompleteAuthToken](/windows/win32/api/sspi/nf-sspi-completeauthtoken),并将输出令牌传递给客户端。 然后,服务器等待来自客户端的返回令牌,然后再次调用 [AcceptSecurityContext (常规)](acceptsecuritycontext--general.md)。
SEC_I_COMPLETE_NEEDED
0x00090313L
函数成功。 服务器必须从客户端生成消息,然后调用 [CompleteAuthToken](/windows/win32/api/sspi/nf-sspi-completeauthtoken) 函数。
SEC_I_CONTINUE_NEEDED
0x00090312L
函数成功。 服务器必须将输出令牌发送到客户端,并等待返回的令牌。 返回的令牌应在 pInput 中传递,以便再次调用 [AcceptSecurityContext (常规)](acceptsecuritycontext--general.md)。
STATUS_LOGON_FAILURE
0xC000006DL
此函数失败。 [AcceptSecurityContext (常规)](acceptsecuritycontext--general.md) 函数在建立指定的上下文后被调用。 使用摘要 SSP 时,可以返回此值。

注解

AcceptSecurityContext (常规) 函数是与 InitializeSecurityContext (常规) 函数对应的服务器。

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

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

  1. 客户端将令牌传输到服务器。
  2. 服务器第一次调用 AcceptSecurityContext (常规), 这会生成一个回复令牌,然后发送到客户端。
  3. 客户端接收令牌并将其传递给 InitializeSecurityContext (常规)。 如果 InitializeSecurityContext (常规) 返回SEC_E_OK,则已完成相互身份验证,并且可以开始安全会话。 如果 InitializeSecurityContext (常规) 返回错误代码,则相互身份验证协商将结束。 否则, InitializeSecurityContext 返回的安全令牌(常规) 将发送到客户端,步骤 2 和步骤 3 将重复。
  4. 请勿在对 AcceptSecurityContext(常规)的并发调用中使用 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 (常规)