用户模式初始化
分布式 (客户端/服务器) 应用程序使用 安全包 来获取经过身份验证的连接和交换消息。 应用程序调用安全支持提供程序接口 (SSPI) 函数,这些函数映射到 SSP/AP 实现的函数,以及 由用户模式 SSP/AP 实现的函数。 此映射由安全提供程序 DLL (Secur32.dll 或Security.dll) 执行,可以动态加载到客户端和服务器进程中。 还可以使用 Secur32.lib 以静态方式链接 DLL。 DLL 和 LIB 都随附了 Microsoft Windows 软件开发工具包 (SDK) 。
如果正确注册了包含安全包的 SSP/AP DLL,则由系统处理将安全包加载到客户端或服务器的进程中。
服务器通过监视端口,等待客户端发送消息,开始获取与客户端的安全连接的过程。 客户端通过调用 SSPI 函数 InitializeSecurityContext (General) 开始获取与服务器的安全连接的过程。 此函数映射到自定义安全包的 SpInitLsaModeContext 函数。 SpInitLsaModeContext 将令牌返回给客户端,客户端将其转发到服务器。
从客户端收到令牌后,服务器将调用 SSPI 函数 AcceptSecurityContext (General) ,该函数被调度到安全包的 SpAcceptLsaModeContext 函数。 如果 SpAcceptLsaModeContext 函数成功,并且无需进行更多处理即可建立安全上下文,则函数应将STATUS_SUCCESS返回给调用方。 如果需要其他处理,该函数应返回SEC_I_CONTINUE_NEEDED,并将令牌返回给服务器。 服务器将令牌转发到客户端,客户端再次调用 InitializeSecurityContext (General) 。
此调用周期可能会根据需要频繁重复,直到建立或失败的经过身份验证的连接。 在此过程中,如果 SpAcceptLsaModeContext 或 SpInitLsaModeContext 函数成功,并且无需进行更多处理即可建立 安全上下文,则函数应将STATUS_SUCCESS返回给调用方。 如果需要其他处理,该函数应返回SEC_I_CONTINUE_NEEDED,并将令牌返回给负责转发它的调用方。
安全包实现的协议决定了此周期的重复次数。 例如,在支持三段相互身份验证的安全包中,调用顺序如下所示:
- 客户端通过调用 InitializeSecurityContext (General) 获取令牌,并将其发送到服务器。 服务器首次 调用 AcceptSecurityContext (常规) ,并取回发送给客户端的回复令牌。
- 客户端使用在对 InitializeSecurityContext (General) 的第二次调用中从服务器收到的令牌,并取回最终令牌。 客户端将此令牌发送到服务器。
- 服务器接收在腿 2 中生成的令牌,该令牌在对 AcceptSecurityContext (General) 的最后调用中使用。
如果 SpAcceptLsaModeContext 和 SpInitLsaModeContext 函数成功,并且无需进行更多处理即可建立安全上下文,则函数应将STATUS_SUCCESS返回给调用方。 此外,如果自定义安全包支持用户模式 SSP/AP 实现的函数,则 SpAcceptLsaModeContext 和 SpInitLsaModeContext 必须通过 MappedContext 参数返回 TRUE。 MappedContext 值不会传递回应用程序;它被 LSA 截获。
当 MappedContext 为 true 时,LSA 将调用 SSP/AP DLL 的 SpUsermodeInitialize 函数。 此函数提供指向每个安全包实现的用户模式函数的指针表。 使用 SpUsermodeInitialize 返回的函数表调用每个包的 SpInstanceInit 函数。 SpInstanceInit 接收指向 用户模式 SSP/AP 调用的 LSA 函数的指针表。