Zabezpieczanie połączenia za pomocą komunikacji wirtualnej holograficznej i interfejsu API OpenXR

W przypadku korzystania z interfejsu API OpenXR wszystkie bezpieczne interfejsy API związane z połączeniem są dostępne w ramach XR_MSFT_holographic_remoting rozszerzenia OpenXR.

Ważne

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

Pamiętaj, że musisz zaimplementować niestandardowe aplikacje zdalne i odtwarzacze, jeśli chcesz włączyć zabezpieczenia połączeń. Obie aplikacje niestandardowe wymagają:

  • Dostawca certyfikatów i moduł sprawdzania poprawności uwierzytelniania, jeśli aplikacja działa jako serwer.
  • Dostawca uwierzytelniania i moduł sprawdzania poprawności certyfikatu, jeśli aplikacja działa jako klient.

Interfejs API openXR jest podobny do interfejsu API Windows Mixed Reality opisanego tutaj. Jednak zamiast implementowania interfejsów kluczowe elementy bezpiecznego połączenia przy użyciu XR_MSFT_holographic_remoting rozszerzenia OpenXR są następującymi wywołaniami zwrotnymi:

  • xrRemotingRequestAuthenticationTokenCallbackMSFT, generuje lub pobiera token uwierzytelniania do wysłania.
  • xrRemotingValidateServerCertificateCallbackMSFT, weryfikuje łańcuch certyfikatów.
  • xrRemotingValidateAuthenticationTokenCallbackMSFT, weryfikuje token uwierzytelniania klienta.
  • xrRemotingRequestServerCertificateCallbackMSFT, podaj aplikację serwera z certyfikatem do użycia.

Uwaga

Dzięki holograficznej komunikacji zdalnej możliwe jest, że odtwarzacz lub zdalny jest serwerem w zależności od potrzeb (aby uzyskać więcej informacji, zobacz Holographic Remoting Terminologia). Jeśli niestandardowa aplikacja zdalna lub niestandardowa odtwarzacza może działać jako klient i serwer, aplikacja musi dostarczyć wszystkie cztery wywołania zwrotne.

Wywołania zwrotne można przekazać do środowiska uruchomieniowego OpenXR komunikacji telefonicznej za pośrednictwem poleceń xrRemotingSetSecureConnectionClientCallbacksMSFT i xrRemotingSetSecureConnectionServerCallbacksMSFT. 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);
    }
}

Statyczne funkcje wywołania zwrotnego wyglądają podobnie i w powyższym przykładzie po prostu wywołają funkcję w obiekcie kontekstu, który jest ustawiony w xrRemotingSetSecureConnectionClientCallbacksMSFT elemecie 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 xrRemotingSetSecureConnectionClientCallbacksMSFT i xrRemotingSetSecureConnectionServerCallbacksMSFT. Ponadto bezpieczne połączenie musi być włączone za pośrednictwem parametru secureConnection w XrRemotingConnectInfoMSFT strukturze lub XrRemotingListenInfoMSFT strukturze w zależności od tego, czy używasz xrRemotingConnectMSFT , 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ż