Bezpieczne połączenie z usługą Holographic Remoting i interfejsem API OpenXR

W przypadku korzystania z interfejsu API OpenXR cały interfejs API związany z bezpiecznym połączeniem jest dostępny w ramach XR_MSFT_holographic_remoting rozszerzenia OpenXR.

Ważne

Aby dowiedzieć się więcej o interfejsie API rozszerzenia OpenXR usługi Holographic Remoting, zapoznaj się ze specyfikacją, którą można znaleźć w repozytorium GitHub przykładów usługi Holographic Remoting.

Pamiętaj, że aby włączyć zabezpieczenia połączeń, musisz zaimplementować niestandardowe aplikacje zdalne i odtwarzacza. Obie aplikacje niestandardowe wymagają:

  • Dostawca certyfikatów i program sprawdzania ważności uwierzytelniania, jeśli aplikacja działa jako serwer.
  • Dostawca uwierzytelniania i program sprawdzania ważności certyfikatu, jeśli aplikacja działa jako klient.

Interfejs API OpenXR jest podobny do Windows Mixed Reality API opisanego tutaj. Jednak zamiast implementowania interfejsów, XR_MSFT_holographic_remoting kluczowymi elementami bezpiecznego połączenia przy użyciu rozszerzenia OpenXR są następujące wywołania zwrotne:

  • xrRemotingRequestAuthenticationTokenCallbackMSFT, generuje lub pobiera token uwierzytelniania do wysłania.
  • xrRemotingValidateServerCertificateCallbackMSFT, weryfikuje łańcuch certyfikatów.
  • xrRemotingValidateAuthenticationTokenCallbackMSFT, weryfikuje token uwierzytelniania klienta.
  • xrRemotingRequestServerCertificateCallbackMSFT, należy podać aplikacji serwera z certyfikatem do użycia.

Uwaga

W przypadku usługi Holographic Remoting możliwe jest, że serwer player lub zdalny jest serwerem w zależności od potrzeb (aby uzyskać więcej informacji, zobacz Terminologia dotycząca komunikacji zdalnej systemu Holographic). Jeśli niestandardowa aplikacja odtwarzacza zdalnego lub niestandardowego może działać jako klient i serwer, aplikacja musi zapewnić wszystkie cztery wywołania zwrotne.

Wywołania zwrotne można dostarczać do środowiska uruchomieniowego OpenXR komunikacji zdalnej za pośrednictwem i xrRemotingSetSecureConnectionClientCallbacksMSFTxrRemotingSetSecureConnectionServerCallbacksMSFT. W tym celu można utworzyć funkcje statyczne dla wywołań zwrotnych:

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);
    }
}

Wszystkie funkcje statycznego wywołania zwrotnego wyglądają podobnie i w powyższym przykładzie wywołują po prostu funkcję w obiekcie kontekstu, który jest ustawiony w obiekcie xrRemotingSetSecureConnectionClientCallbacksMSFT lub xrRemotingSetSecureConnectionServerCallbacksMSFT. Rzeczywista implementacja wywołań zwrotnych jest następnie wykonywana wewnątrz funkcji członkowskich obiektu kontekstu:

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.
    }
}

Teraz możesz podać wywołania zwrotne do i xrRemotingSetSecureConnectionClientCallbacksMSFTxrRemotingSetSecureConnectionServerCallbacksMSFT. Ponadto należy włączyć bezpieczne połączenie za pośrednictwem parametru secureConnection XrRemotingConnectInfoMSFTXrRemotingListenInfoMSFT w strukturze lub strukturze w zależności od tego, czy używasz xrRemotingConnectMSFT programu , czy :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));
}

Uwaga

Szczegółowy przykład można znaleźć w przykładowej aplikacji OpenXR.

Zobacz też