Öğretici: Azure Remote Rendering ve model depolamanın güvenliğini sağlama

Bu öğreticide şunların nasıl yapıldığını öğreneceksiniz:

  • Veri modelleri içeren Depolama Azure Blob Azure Remote Rendering sağlama
  • Azure AD ile kimlik doğrulaması ile Azure Remote Rendering erişin
  • Kimlik doğrulaması için Azure kimlik Azure Remote Rendering kullanma

Önkoşullar

Ek güvenlik neden gereklidir?

Uygulamanın geçerli durumu ve Azure kaynaklarınıza erişimi şu şekildedir:

İlk güvenlik

Hem "AccountID + AccountKey" hem de "URL + SAS Belirteci" temelde bir kullanıcı adı ve parolayı birlikte depolar. Örneğin, "AccountID + AccountKey" açığa çıkarılmışsa, bir saldırganın sizin izniniz olmadan ARR kaynaklarınızı kullanması sizin için önemsiz olabilir.

Azure Blob Depolama'da içeriğinizin güvenliğini Depolama

Azure Remote Rendering Doğru yapılandırmayla Azure Blob depolama Depolama güvenli bir şekilde erişin. Bkz. Nasıl yapılandırılır: Blob depolama hesaplarınız ile Azure Remote Rendering için depolama hesaplarını bağlama.

Bağlı blob depolaması kullanırken modelleri yüklerken biraz farklı yöntemler kullanabilirsiniz:

var loadModelParams = new LoadModelFromSasOptions(modelPath, modelEntity);
var task = ARRSessionService.CurrentActiveSession.Connection.LoadModelFromSasAsync(loadModelParams);

Yukarıdaki satırlarda FromSas params ve session eyleminin sürümü mektedir. Sas olmayan sürümlere dönüştürülmesi gerekir:

var loadModelParams = new LoadModelOptions(storageAccountPath, blobName, modelPath, modelEntity);
var task = ARRSessionService.CurrentActiveSession.Connection.LoadModelAsync(loadModelParams);

Bağlı blob depolama hesabından özel bir model yüklemek için RemoteRenderingCoordinator'da değişiklik bakalım.

  1. Henüz tamamlamadısanız, ARR örneğinize Blob depolama örneğinize erişim izni vermek için Nasıl uzla: Depolama hesaplarını bağlama Depolama olun.

  2. Aşağıdaki değiştirilmiş LoadModel yöntemini RemoteRenderingCoordinator'a geçerli LoadModel yönteminin hemen altına ekleyin:

    /// <summary>
    /// Loads a model from blob storage that has been linked to the ARR instance
    /// </summary>
    /// <param name="storageAccountName">The storage account name, this contains the blob containers </param>
    /// <param name="blobName">The blob container name, i.e. arroutput</param>
    /// <param name="modelPath">The relative path inside the container to the model, i.e. test/MyCustomModel.arrAsset</param>
    /// <param name="parent">The parent Transform for this remote entity</param>
    /// <param name="progress">A call back method that accepts a float progress value [0->1]</param>
    /// <returns></returns>
    public async Task<Entity> LoadModel(string storageAccountName, string blobName, string modelPath, Transform parent = null, Action<float> progress = null)
    {
        //Create a root object to parent a loaded model to
        var modelEntity = ARRSessionService.CurrentActiveSession.Connection.CreateEntity();
    
        //Get the game object representation of this entity
        var modelGameObject = modelEntity.GetOrCreateGameObject(UnityCreationMode.DoNotCreateUnityComponents);
    
        //Ensure the entity will sync its transform with the server
        var sync = modelGameObject.GetComponent<RemoteEntitySyncObject>();
        sync.SyncEveryFrame = true;
    
        //Parent the new object under the defined parent
        if (parent != null)
        {
            modelGameObject.transform.SetParent(parent, false);
            modelGameObject.name = parent.name + "_Entity";
        }
    
        //Load a model that will be parented to the entity
        var loadModelParams = new LoadModelOptions($"{storageAccountName}.blob.core.windows.net", blobName, modelPath, modelEntity);
        var loadModelAsync = ARRSessionService.CurrentActiveSession.Connection.LoadModelAsync(loadModelParams, progress);
        var result = await loadModelAsync;
        return modelEntity;
    }
    

    Çoğu bölümde bu kod özgün yöntemle aynıdır, ancak yöntem çağrılarının SAS sürümünü SAS dışı LoadModel sürümlerle değiştiririz.

    ve ek girişleri storageAccountName blobName de bağımsız değişkenlere eklenmiştir. Bu yeni LoadModel yöntemini, ilk öğreticide oluşturduğumız ilk LoadTestModel yöntemine benzer başka bir yöntemden çağıracak.

  3. Aşağıdaki yöntemi LoadTestModel'den hemen sonra RemoteRenderingCoordinator'a ekleyin

    private bool loadingLinkedCustomModel = false;
    
    [SerializeField]
    private string storageAccountName;
    public string StorageAccountName {
        get => storageAccountName.Trim();
        set => storageAccountName = value;
    }
    
    [SerializeField]
    private string blobContainerName;
    public string BlobContainerName {
        get => blobContainerName.Trim();
        set => blobContainerName = value;
    }
    
    [SerializeField]
    private string modelPath;
    public string ModelPath {
        get => modelPath.Trim();
        set => modelPath = value;
    }
    
    [ContextMenu("Load Linked Custom Model")]
    public async void LoadLinkedCustomModel()
    {
        if (CurrentCoordinatorState != RemoteRenderingState.RuntimeConnected)
        {
            Debug.LogError("Please wait for the runtime to connect before loading the test model. Try again later.");
            return;
        }
        if (loadingLinkedCustomModel)
        {
            Debug.Log("Linked Test model already loading or loaded!");
            return;
        }
        loadingLinkedCustomModel = true;
    
        // Create a parent object to use for positioning
        GameObject testParent = new GameObject("LinkedCustomModel");
        testParent.transform.position = new Vector3(0f, 0f, 3f);
    
        await LoadModel(StorageAccountName, BlobContainerName, ModelPath, testParent.transform, (progressValue) => Debug.Log($"Loading Test Model progress: {Math.Round(progressValue * 100, 2)}%"));
    }
    

    Bu kod RemoteRenderingCoordinator bileşeninize üç ek dize değişkeni ekler. RemoteRenderingCoordinator bileşeninin Depolama Adı, Blob Kapsayıcı Adı ve Model Yolu'nun vurgulanmış olduğu ekran görüntüsü.

  4. Değerlerinizi RemoteRenderingCoordinator bileşenine ekleyin. Model dönüştürme için Hızlı Başlangıç'ı izlenimli,değerleriniz şu şekildedir:

    • Depolama Adı: Depolama hesabınız için seçtiğiniz genel benzersiz ad olan depolama hesabı adınız. Bu hızlı başlangıçta arrtutorialstorage değeri farklı olacak.
    • Blob Kapsayıcı Adı: arroutput, Blob Depolama Kapsayıcısı
    • Model Yolu: dosyada tanımlanan "outputFolderPath" ve "outputAssetFileName" arrconfig.js birleşimi. Hızlı başlangıçta bu "outputFolderPath":"converted/robot", "outputAssetFileName": "robot.arrAsset" şeklindedir. Bu da Model Yolu değerinin "converted/robot/robot.arrAsset" olmasıyla sonuçlansa değeriniz farklı olur.

    İpucu

    Conversion.ps1 betiği "-UseContainerSas" bağımsız değişkeni olmadan çalıştırdısanız, betik SAS belirteci yerine yukarıdaki değerlerin hepsini çıkış olarak verir. Bağlı Model

  5. Şu an için GameObject TestModelini kaldırın veya devre dışı bırakarak özel modelinizin yüklensin.

  6. Sahneyi oynat ve uzak oturuma bağlan.

  7. RemoteRenderingCoordinator'ınıza sağ tıklayın ve Bağlı Özel Modeli Yükle'yi seçin. Bağlı modeli yükleme

Bu adımlar, sas belirteci yerel uygulamadan kaldırarak uygulamanın güvenliğini artırmıştır.

Artık uygulamanın geçerli durumu ve Azure kaynaklarınıza erişimi şu şekildedir:

Daha iyi güvenlik

Yerel uygulamadan kaldırmak için bir "parola" daha (AccountKey) vardır. Bu, Azure Active Directory (AAD) kimlik doğrulaması kullanılarak yapılabilir.

Azure Active Directory (Azure AD) kimlik doğrulaması

AAD kimlik doğrulaması, hangi kişilerin veya grupların ARR'i daha denetimli bir şekilde kullanmakta olduğunu belirlemenize olanak sağlar. ARR, Hesap Anahtarı kullanmak yerine Erişim Belirteçlerini kabul etmek için yerleşik destek sağlar. Erişim Belirteçlerini, yalnızca istenen kaynağın belirli bölümlerinin kilidini açan sınırlı, kullanıcıya özgü bir anahtar olarak düşünebilirsiniz.

RemoteRenderingCoordinator betiğinde, uzak oturum yönetimini yapılandırmak için kullanılan SessionConfiguration nesnesini döndüren bir yöntemi tutan ARRCredentialGetter adlı bir temsilci vardır. ARRCredentialGetter'a farklı bir yöntem atayabilirsiniz. Bu da Azure oturum açma akışı kullanarak Azure Erişim Belirteci içeren SessionConfiguration nesnesi oluşturmamızı sağlar. Bu Erişim Belirteci, oturum açmada olan kullanıcıya özeldir.

  1. Yeni bir Azure Active Directory uygulaması kaydetmeyi ve ARR örneğine erişimi yapılandırmayı içeren, dağıtılan uygulamalar için kimlik doğrulamasını yapılandırma:Nasıl yapılandırılır? adımlarını izleyin.

  2. Yeni AAD uygulamasını yapılandırdikten sonra AAD uygulamanın aşağıdaki görüntülere benzini kontrol edin:

    AAD Uygulaması -> Kimlik Doğrulama Uygulaması kimlik doğrulaması

    AAD Uygulaması -> API İzinleri Uygulama API'leri

  3. Yapılandırma hesabı Remote Rendering yapılandırmanızı aşağıdaki görüntüye benzer şekilde kontrol edin:

    AAR -> AccessControl (IAM) ARR Rolü

    Not

    Sahip rolü, oturumları istemci uygulaması aracılığıyla yönetmek için yeterli değildir. Oturumları yönetme yeteneği vermek istediğiniz her kullanıcı için, İstemcisi rolü Remote Rendering gerekir. Oturumları yönetmek ve modelleri dönüştürmek istediğiniz her kullanıcı için Yönetici rolü Remote Rendering gerekir.

Azure tarafı olduğu için kodunuzun AAR hizmetine nasıl bağlanacaklarını değiştirmemiz gerekiyor. Bunu, yeni bir SessionConfiguration nesnesi dönecek baseARRAuthentication örneğini kullanarak yapabiliriz. Bu durumda, hesap bilgileri Azure Erişim Belirteci ile yapılandırılır.

  1. AADAuthentication adlı yeni bir betik oluşturun ve kodunu aşağıdakiyle değiştirin:

    // Copyright (c) Microsoft Corporation. All rights reserved.
    // Licensed under the MIT License. See LICENSE in the project root for license information.
    
    using Microsoft.Azure.RemoteRendering;
    using Microsoft.Identity.Client;
    using System;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using UnityEngine;
    
    public class AADAuthentication : BaseARRAuthentication
    {
        [SerializeField]
        private string activeDirectoryApplicationClientID;
        public string ActiveDirectoryApplicationClientID
        {
            get => activeDirectoryApplicationClientID.Trim();
            set => activeDirectoryApplicationClientID = value;
        }
    
        [SerializeField]
        private string azureTenantID;
        public string AzureTenantID
        {
            get => azureTenantID.Trim();
            set => azureTenantID = value;
        }
    
        [SerializeField]
        private string azureRemoteRenderingDomain;
        public string AzureRemoteRenderingDomain
        {
            get => azureRemoteRenderingDomain.Trim();
            set => azureRemoteRenderingDomain = value;
        }
    
        [SerializeField]
        private string azureRemoteRenderingAccountID;
        public string AzureRemoteRenderingAccountID
        {
            get => azureRemoteRenderingAccountID.Trim();
            set => azureRemoteRenderingAccountID = value;
        }
    
        [SerializeField]
        private string azureRemoteRenderingAccountDomain;
        public string AzureRemoteRenderingAccountDomain
        {
            get => azureRemoteRenderingAccountDomain.Trim();
            set => azureRemoteRenderingAccountDomain = value;
        }    
    
        public override event Action<string> AuthenticationInstructions;
    
        string authority => "https://login.microsoftonline.com/" + AzureTenantID;
    
        string redirect_uri = "https://login.microsoftonline.com/common/oauth2/nativeclient";
    
        string[] scopes => new string[] { "https://sts.mixedreality.azure.com//.default" };
    
        public void OnEnable()
        {
            RemoteRenderingCoordinator.ARRCredentialGetter = GetAARCredentials;
            this.gameObject.AddComponent<ExecuteOnUnityThread>();
        }
    
        public async override Task<SessionConfiguration> GetAARCredentials()
        {
            var result = await TryLogin();
            if (result != null)
            {
                Debug.Log("Account signin successful " + result.Account.Username);
    
                var AD_Token = result.AccessToken;
    
                return await Task.FromResult(new SessionConfiguration(AzureRemoteRenderingAccountDomain, AzureRemoteRenderingDomain, AzureRemoteRenderingAccountID, "", AD_Token, ""));
            }
            else
            {
                Debug.LogError("Error logging in");
            }
            return default;
        }
    
        private Task DeviceCodeReturned(DeviceCodeResult deviceCodeDetails)
        {
            //Since everything in this task can happen on a different thread, invoke responses on the main Unity thread
            ExecuteOnUnityThread.Enqueue(() =>
            {
                // Display instructions to the user for how to authenticate in the browser
                Debug.Log(deviceCodeDetails.Message);
                AuthenticationInstructions?.Invoke(deviceCodeDetails.Message);
            });
    
            return Task.FromResult(0);
        }
    
        public override async Task<AuthenticationResult> TryLogin()
        {
            var clientApplication = PublicClientApplicationBuilder.Create(ActiveDirectoryApplicationClientID).WithAuthority(authority).WithRedirectUri(redirect_uri).Build();
            AuthenticationResult result = null;
            try
            {
                var accounts = await clientApplication.GetAccountsAsync();
    
                if (accounts.Any())
                {
                    result = await clientApplication.AcquireTokenSilent(scopes, accounts.First()).ExecuteAsync();
    
                    return result;
                }
                else
                {
                    try
                    {
                        result = await clientApplication.AcquireTokenWithDeviceCode(scopes, DeviceCodeReturned).ExecuteAsync(CancellationToken.None);
                        return result;
                    }
                    catch (MsalUiRequiredException ex)
                    {
                        Debug.LogError("MsalUiRequiredException");
                        Debug.LogException(ex);
                    }
                    catch (MsalServiceException ex)
                    {
                        Debug.LogError("MsalServiceException");
                        Debug.LogException(ex);
                    }
                    catch (MsalClientException ex)
                    {
                        Debug.LogError("MsalClientException");
                        Debug.LogException(ex);
                        // Mitigation: Use interactive authentication
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError("Exception");
                        Debug.LogException(ex);
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError("GetAccountsAsync");
                Debug.LogException(ex);
            }
    
            return null;
        }
    }
    

Not

Bu kod hiçbir şekilde eksiksiz değildir ve ticari bir uygulama için hazır değildir. Örneğin, en azından büyük olasılıkla oturum açma özelliği de eklemek istersiniz. Bu, istemci uygulaması Task RemoveAsync(IAccount account) tarafından sağlanan yöntemi kullanılarak yapılabilir. Bu kod yalnızca öğretici kullanımına yöneliktir, uygulamanız uygulamanıza özgü olur.

Kod ilk olarak AquireTokenSilent kullanarak belirteci sessizce almaya çalışır. Kullanıcı bu uygulamanın kimlik doğrulamalarını daha önce yaptı ise bu başarılı olur. Başarılı olmazsa daha kullanıcıyla ilgili bir stratejiye geç.

Bu kod için, erişim belirteci almak için cihaz kod akışını kullanıyoruz. Bu akış, kullanıcının bir bilgisayarda veya mobil cihazda Azure hesabında oturum açmasını ve sonuçta elde edilen belirteci HoloLens sağlar.

ARR açısından bu sınıfın en önemli bölümü şu çizgidir:

return await Task.FromResult(new SessionConfiguration(AzureRemoteRenderingAccountDomain, AzureRemoteRenderingDomain, AzureRemoteRenderingAccountID, "", AD_Token, ""));

Burada uzaktan işleme etki alanını, hesap kimliğini, hesap etki alanını ve erişim belirteci kullanarak yeni bir SessionConfiguration nesnesi oluşturuz. Bu belirteç daha sonra kullanıcı daha önce yapılandırılan rol tabanlı izinlere göre yetkilendiril olduğu sürece uzaktan işleme oturumlarını sorgulamak, oluşturmak ve birleştirmek için ARR hizmeti tarafından kullanılır.

Bu değişiklikle, uygulamanın geçerli durumu ve Azure kaynaklarınıza erişimi şu şekilde olur:

Daha da iyi güvenlik

Kullanıcı Kimlik Bilgileri cihazda depolanmış (veya bu durumda bile cihaza girili) için risk çok düşüktür. Cihaz artık ARR'ye erişmek için kullanıcıya özgü, sınırlı bir Erişim Belirteci kullanıyor. Bu belirteç blob verilerine erişmek için erişim denetimi (IAM) Depolama. Bu iki adım, kaynak koddan "parolaları" tamamen kaldırmış ve güvenliği önemli ölçüde artırmıştır. Ancak, kullanılabilir en fazla güvenlik bu değildir; modelin ve oturum yönetiminin bir web hizmetine taşınması güvenliği daha da geliştirecek. Ek güvenlik konuları Ticari Hazır olma bölümünde ele alınmıştır.

AAD Kimlik Doğrulamayı Test Etme

Unity Düzenleyicisi'nde, AAD Kimlik Doğrulaması etkin olduğunda, uygulamayı her başlatan zaman kimlik doğrulaması gerekir. Cihazda kimlik doğrulama adımı ilk kez olur ve yalnızca belirteci süresi dolduğunda veya geçersiz kılındiğinde yeniden gerekli olur.

  1. AAD Kimlik Doğrulaması bileşenini RemoteRenderingCoordinator GameObject'e ekleyin.

    AAD kimlik doğrulama bileşeni

Not

ARRörnekleri deposundan tamamlanan projeyi kullanıyorsanız, başlığının yanındaki onay kutusuna tıklayarak AAD Kimlik Doğrulaması bileşenini etkinleştirin.

  1. İstemci Kimliği ve Kiracı Kimliği için değerlerinizi girin. Bu değerler Uygulama Kaydınıza Genel Bakış Sayfasında bulunabilir:

    • Active Directory Uygulama İstemci Kimliği, AAD uygulama kaydında bulunan Uygulama (istemci) kimliğidir (aşağıdaki görüntüye bakın).
    • Azure Kiracı Kimliği, AAD uygulama kaydınıza (aşağıdaki görüntüye bakın) bulunan Dizin (kiracı) kimliğidir.
    • Azure Remote Rendering Etki Alanı, RemoteRenderingCoordinator'ın Etki Alanı'Remote Rendering kullanılır.
    • Azure Remote Rendering Kimliği, RemoteRenderingCoordinator için kullanmakta olduğu Hesap Kimliği ile aynıdır.
    • Azure Remote Rendering Etki Alanı, RemoteRenderingCoordinator'da kullanmakta olduğunu hesap etki alanıdır.

    Uygulama (istemci) KIMLIĞINI ve dizin (kiracı) KIMLIĞINI vurgulayan ekran görüntüsü.

  2. Unity düzenleyicisinde oynat ' a ve bir oturumu çalıştırmak için onay düğmesine basın. AAD kimlik doğrulama bileşeni bir görünüm denetleyicisine sahip olduğundan, oturum yetkilendirme kalıcı panelinden sonra bir istem görüntülemek için otomatik olarak bağlanır.

  3. Appmenu'in sağındaki panelde bulunan yönergeleri izleyin. Şuna benzer bir şey görmeniz gerekir:  AppMenu 'nin sağında görüntülenen yönerge panelini gösteren çizim.

    Belirtilen kodu ikincil cihazınıza (veya aynı cihaza tarayıcınızda) girdikten ve kimlik bilgilerinizi kullanarak oturum açtıktan sonra, istenen uygulamaya bir erişim belirteci döndürülür, bu örnekte Unity Düzenleyicisi kullanılır.

Bu noktadan sonra, uygulamadaki her şey normal olarak devam etmelidir. Evrelerin beklendiği gibi ilerlemeden devam ediyorsanız, Unity konsolunda herhangi bir hata olup olmadığını denetleyin.

Cihaza oluştur

MSAL to Device kullanarak bir uygulama oluşturuyorsanız projenizin varlıklar klasörüne bir dosya eklemeniz gerekir. Bu, derleyicinin öğretici varlıklarına dahil olan Microsoft.Identity.Client.dll kullanarak uygulamayı doğru şekilde oluşturmasına yardımcı olur.

  1. link.xml adlı varlıklara yeni bir dosya ekleyin

  2. Dosyasına aşağıdakileri ekleyin:

    <linker>
        <assembly fullname="Microsoft.Identity.Client" preserve="all"/>
        <assembly fullname="System.Runtime.Serialization" preserve="all"/>
        <assembly fullname="System.Core">
            <type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
        </assembly>
    </linker>
    
  3. Değişiklikleri kaydedin

hızlı başlangıç: HoloLens Unity örneğini dağıtmabölümünde bulunan adımları izleyin-HoloLens derlemek için örnek Project oluşturun.

Sonraki adımlar

Bu öğretici kümesinin geri kalanı, Azure uzaktan Işleme kullanan üretime yönelik bir uygulama oluşturmaya yönelik kavramsal konular içerir.