使用全息远程处理和 OpenXR API 建立安全连接

使用 OpenXR API 时,所有与安全连接相关的 API 都可作为 XR_MSFT_holographic_remoting OpenXR 扩展的一部分使用。

重要

若要了解全息远程处理 OpenXR 扩展 API,请查看可在全息远程处理示例 github 存储库中找到的规范

请记住,如果要启用连接安全性,则需要实现自定义远程和播放器应用。 这两个自定义应用都需要:

  • 证书提供程序和身份验证验证程序(如果应用作为服务器运行)。
  • 身份验证提供程序和证书验证程序(如果应用作为客户端运行)。

OpenXR API 类似于此处所述的 Windows Mixed Reality API。 但是,使用 XR_MSFT_holographic_remoting OpenXR 扩展进行安全连接的关键元素不是实现接口,而是以下回调:

  • xrRemotingRequestAuthenticationTokenCallbackMSFT,生成或检索要发送的身份验证令牌。
  • xrRemotingValidateServerCertificateCallbackMSFT,验证证书链。
  • xrRemotingValidateAuthenticationTokenCallbackMSFT,验证客户端身份验证令牌。
  • xrRemotingRequestServerCertificateCallbackMSFT,为服务器应用程序提供要使用的证书。

注意

通过全息远程处理,可以根据需要将播放器或远程设备作为服务器(有关详细信息,请参阅全息远程处理术语)。 如果自定义远程或自定义播放器应用程序可以作为客户端和服务器运行,应用必须提供所有四个回调。

可以通过 xrRemotingSetSecureConnectionClientCallbacksMSFTxrRemotingSetSecureConnectionServerCallbacksMSFT 向远程处理 OpenXR 运行时提供这些回调。 为此,可以为回调创建静态函数:

class SecureConnectionCallbacks {
public:
    ...

    // Static callbacks
    static XrResult XRAPI_CALL
    RequestAuthenticationTokenStaticCallback(XrRemotingAuthenticationTokenRequestMSFT* authenticationTokenRequest) {
        if (!authenticationTokenRequest->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(authenticationTokenRequest->context)
            ->RequestAuthenticationToken(authenticationTokenRequest);
    }

    static XrResult XRAPI_CALL
    ValidateServerCertificateStaticCallback(XrRemotingServerCertificateValidationMSFT* serverCertificateValidation) {
        if (!serverCertificateValidation->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(serverCertificateValidation->context)
            ->ValidateServerCertificate(serverCertificateValidation);
    }

    static XrResult XRAPI_CALL
    ValidateAuthenticationTokenStaticCallback(XrRemotingAuthenticationTokenValidationMSFT* authenticationTokenValidation) {
        if (!authenticationTokenValidation->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(authenticationTokenValidation->context)
            ->ValidateAuthenticationToken(authenticationTokenValidation);
    }

    static XrResult XRAPI_CALL
    RequestServerCertificateStaticCallback(XrRemotingServerCertificateRequestMSFT* serverCertificateRequest) {
        if (!serverCertificateRequest->context) {
            return XR_ERROR_RUNTIME_FAILURE;
        }
        return reinterpret_cast<SecureConnectionCallbacks*>(serverCertificateRequest->context)
            ->RequestServerCertificate(serverCertificateRequest);
    }
}

静态回调函数看起来都类似,在上面的示例中,它们只在上下文对象上调用一个函数,该对象在 xrRemotingSetSecureConnectionClientCallbacksMSFTxrRemotingSetSecureConnectionServerCallbacksMSFT 中设置。 然后,在上下文对象的成员函数内完成回调的实际实现:

class SecureConnectionCallbacks {   
    ...

private:
    // The client has to provide a token and has to validate the certificate.
    XrResult RequestAuthenticationToken(XrRemotingAuthenticationTokenRequestMSFT* authenticationTokenRequest) {
        // To provide a token fill out the authenticationTokenRequest with your token.
    }
    XrResult ValidateServerCertificate(XrRemotingServerCertificateValidationMSFT* serverCertificateValidation) {
        // Validate the certificate.
    }

    // The server has to provide a certificate and hast to validate the token.
    XrResult ValidateAuthenticationToken(XrRemotingAuthenticationTokenValidationMSFT* authenticationTokenValidation) {
        // Validate the token.
    }
    XrResult RequestServerCertificate(XrRemotingServerCertificateRequestMSFT* serverCertificateRequest) {
        // To provide a certificate fill out the serverCertificateRequest with your certificate.
    }
}

现在,可以为 xrRemotingSetSecureConnectionClientCallbacksMSFTxrRemotingSetSecureConnectionServerCallbacksMSFT 提供回调。 此外,需要通过 XrRemotingConnectInfoMSFT 结构或 XrRemotingListenInfoMSFT 结构上的 secureConnection 参数启用安全连接,具体取决于你使用的是 xrRemotingConnectMSFT 还是 xrRemotingListenMSFT

...

SecureConnectionCallbacks callbackObject;

...

if (client) 
{
    XrRemotingSecureConnectionClientCallbacksMSFT clientCallbacks{static_cast<XrStructureType>(XR_TYPE_REMOTING_SECURE_CONNECTION_CLIENT_CALLBACKS_MSFT);
    clientCallbacks.context = &callbackObject;
    clientCallbacks.requestAuthenticationTokenCallback = SecureConnectionCallbacks::RequestAuthenticationTokenStaticCallback;
    clientCallbacks.validateServerCertificateCallback = SecureConnectionCallbacks::ValidateServerCertificateStaticCallback;
    clientCallbacks.performSystemValidation = true;
    CHECK_XRCMD(m_extensions.xrRemotingSetSecureConnectionClientCallbacksMSFT(m_instance.Get(), m_systemId, &clientCallbacks));
    
    ...

    connectInfo.secureConnection = true; // Enable secure connection!
    CHECK_XRCMD(m_extensions.xrRemotingConnectMSFT(m_instance.Get(), m_systemId, &connectInfo));
}

if (server) 
{
    XrRemotingSecureConnectionServerCallbacksMSFT serverCallbacks{static_cast<XrStructureType>(XR_TYPE_REMOTING_SECURE_CONNECTION_SERVER_CALLBACKS_MSFT);
    serverCallbacks.context = &callbackObject;
    serverCallbacks.requestServerCertificateCallback = SecureConnectionCallbacks::RequestServerCertificateStaticCallback;
    serverCallbacks.validateAuthenticationTokenCallback = SecureConnectionCallbacks::ValidateAuthenticationTokenStaticCallback;
    serverCallbacks.authenticationRealm = /*YourAuthenticationRealm*/;
    CHECK_XRCMD(m_extensions.xrRemotingSetSecureConnectionServerCallbacksMSFT(m_instance.Get(), m_systemId, &serverCallbacks));

    ...

    listenInfo.secureConnection = true; // Enable secure connection!
    CHECK_XRCMD(m_extensions.xrRemotingListenMSFT(m_instance.Get(), m_systemId, &listenInfo));
}

注意

可在 OpenXR 示例应用中找到详细的示例。

另请参阅